带有List <BaseClass>和编辑器模板的ViewModel
我有一个观点,列出添加到平面图的表格。 表派生自TableInputModel
以允许RectangleTableInputModel
, CircleTableInputModel
等
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)
并最终失踪的难题和平是TableInputModel
types的自定义模型联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中没有这样的绑定