带有List <BaseClass>和编辑器模板的ViewModel

我有一个观点,列出添加到平面图的表格。 表派生自TableInputModel以允许RectangleTableInputModelCircleTableInputModel

ViewModel有一个TableInputModel的列表,它们都是派生types之一。

我有一个派生types的每个部分视图,并给出一个混合派生typesList框架知道如何呈现它们。

但是,在提交表单时,types信息会丢失。 我已经尝试使用自定义模型联编程序,但是因为types信息在提交时会丢失,所以无法工作…

有没有人试过这个?

假设你有以下型号:

 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) 

并最终失踪的难题和平是TableInputModeltypes的自定义模型联TableInputModel ,它将使用发布的隐藏字段值来获取types并实例化正确的实现:

 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操作中,模型数组将被正确地初始化为正确的types。

在mvccontrib中有“Derived Type Model Binder” 。 但不幸的是,在mvccontrib版本3中没有这样的绑定