Обновление: В примере теперь используется AJAX JSON POST
Если вам необходимо использовать абстрактный тип, вы можете предоставить пользовательскую связующую модель для создания конкретного экземпляра.,Пример показан ниже:
Связыватель модели / модели
public abstract class Student
{
public abstract int Age { get; set; }
public abstract string Name { get; set; }
}
public class GoodStudent : Student
{
public override int Age { get; set; }
public override string Name { get; set; }
}
public class BadStudent : Student
{
public override int Age { get; set; }
public override string Name { get; set; }
}
public class StudentBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var values = (ValueProviderCollection) bindingContext.ValueProvider;
var age = (int) values.GetValue("Age").ConvertTo(typeof (int));
var name = (string) values.GetValue("Name").ConvertTo(typeof(string));
return age > 10 ? (Student) new GoodStudent { Age = age, Name = name } : new BadStudent { Age = age, Name = name };
}
}
Действия контроллера
public ActionResult Index()
{
return View(new GoodStudent { Age = 13, Name = "John Smith" });
}
[HttpPost]
public ActionResult Index(Student student)
{
return View(student);
}
Вид
@model AbstractTest.Models.Student
@using (Html.BeginForm())
{
<div id="StudentEditor">
<p>Age @Html.TextBoxFor(m => m.Age)</p>
<p>Name @Html.TextBoxFor(m => m.Name)</p>
<p><input type="button" value="Save" id="Save" /></p>
</div>
}
<script type="text/javascript">
$('document').ready(function () {
$('input#Save').click(function () {
$.ajax({
url: '@Ajax.JavaScriptStringEncode(Url.Action("Index"))',
type: 'POST',
data: GetStudentJsonData($('div#StudentEditor')),
contentType: 'application/json; charset=utf-8',
success: function (data, status, jqxhr) { window.location.href = '@Url.Action("Index")'; }
});
});
});
var GetStudentJsonData = function ($container) {
return JSON.stringify({
'Age': $container.find('input#Age').attr('value'),
'Name': $container.find('input#Name').attr('value')
});
};
</script>
Добавлено в Global.asax.cs
protected void Application_Start()
{
...
ModelBinders.Binders.Add(new KeyValuePair<Type, IModelBinder>(typeof(Student), new StudentBinder()));
}