asp.net-mvc – 具有列表和编辑器模板的ViewModel

我有一个视图列出被添加到平面图的表。表派生自TableInputModel以允许RectangleTableInputModel,CircleTableInputModel等

viewmodel有一个TableInputModel的列表,它们都是派生类型之一。

我有一个部分视图的每个派生类型,并给出一个混合派生类型的列表框架知道如何渲染它们。

但是,在提交表单时,类型信息丢失。我试过一个自定义模型绑定器,但因为类型信息丢失时,它提交,它不工作…

有没有人试过这个?

解决方法

假设您有以下型号:
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动作中,模型数组将正确地用正确的类型初始化。

相关文章

这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识...
Some samples are below for ASP.Net web form controls:(fr...
问题描述: 对于未定义为 System.String 的列,唯一有效的值...
最近用到了CalendarExtender,结果不知道为什么发生了错位,...
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence cha...