假设您有以下模型:
public abstract class TableInputModel
{
}
public class RectangleTableInputModel : TableInputModel
{
public string Foo { get; set; }
}
public class CircleTableInputModel : TableInputModel
{
public string Bar { get; set; }
}
还有以下控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new TableInputModel[]
{
new RectangleTableInputModel(),
new CircleTableInputModel()
};
return View(model);
}
[HttpPost]
public ActionResult Index(TableInputModel[] model)
{
return View(model);
}
}
现在您可以编写视图了。
主视图Index.cshtml:
@model TableInputModel[]
@using (Html.BeginForm())
{
@Html.EditorForModel()
<input type="submit" value="OK" />
}
以及相应的编辑器模板。
~/Views/Home/EditorTemplates/RectangleTableInputModel.cshtml:
@model RectangleTableInputModel
<h3>Rectangle</h3>
@Html.Hidden("ModelType", Model.GetType())
@Html.EditorFor(x => x.Foo)
~/Views/Home/EditorTemplates/CircleTableInputModel.cshtml:
@model CircleTableInputModel
<h3>Circle</h3>
@Html.Hidden("ModelType", Model.GetType())
@Html.EditorFor(x => x.Bar)
最后的难题是 TableInputModel 类型的自定义模型绑定器,它将使用发布的隐藏字段值来获取类型并实例化正确的实现:
public class TableInputModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var typeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType");
var type = Type.GetType(
(string)typeValue.ConvertTo(typeof(string)),
true
);
var model = Activator.CreateInstance(type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
return model;
}
}
将在Application_Start注册:
ModelBinders.Binders.Add(typeof(TableInputModel), new TableInputModelBinder());
差不多就是这样。现在,在 Index Post 操作中,模型数组将使用正确的类型正确初始化。