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

前端之家收集整理的这篇文章主要介绍了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动作中,模型数组将正确地用正确的类型初始化。

原文链接:https://www.f2er.com/aspnet/254636.html

猜你在找的asp.Net相关文章