Asp.net mvc 3 mvc3 razor editortemplate与抽象类

Asp.net mvc 3 mvc3 razor editortemplate与抽象类,asp.net-mvc-3,razor,mvc-editor-templates,Asp.net Mvc 3,Razor,Mvc Editor Templates,这是我们的后续问题 我举的例子很简单。子集合实际上是来自抽象基类的对象集合。因此集合有一个基类列表 我已经为每个派生类创建了一个模板,并尝试使用if child类型,然后以字符串形式给出模板名称。模板将呈现到视图中,但不会在回发上填充 我不确定如何使用editorfor位与模板一起选择正确的模板,并将信息编组回父容器中的子对象。您可以使用自定义模型绑定器。让我们举个例子 型号: public class MyViewModel { public IList<BaseClass>

这是我们的后续问题

我举的例子很简单。子集合实际上是来自抽象基类的对象集合。因此集合有一个基类列表

我已经为每个派生类创建了一个模板,并尝试使用if child类型,然后以字符串形式给出模板名称。模板将呈现到视图中,但不会在回发上填充


我不确定如何使用editorfor位与模板一起选择正确的模板,并将信息编组回父容器中的子对象。

您可以使用自定义模型绑定器。让我们举个例子

型号:

public class MyViewModel
{
    public IList<BaseClass> Children { get; set; }
}

public abstract class BaseClass
{
    public int Id { get; set; }

    [HiddenInput(DisplayValue = false)]
    public string ModelType
    {
        get { return GetType().FullName; }
    }
}

public class Derived1 : BaseClass
{
    public string Derived1Property { get; set; }
}

public class Derived2 : BaseClass
{
    public string Derived2Property { get; set; }
}
视图(
~/Views/Home/Index.cshtml
):

以及
Dervied2
类型的编辑器模板(
~/Views/Home/EditorTemplates/Derived2.cshtml
):

现在只剩下一个自定义模型绑定器,它将使用隐藏字段值实例化集合中的适当类型:

public class BaseClassModelBinder : 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;
    }
}
将在
应用程序\u Start
中注册:

ModelBinders.Binders.Add(typeof(BaseClass), new BaseClassModelBinder());

令人惊叹的。。。那是一种享受。。。我不得不回去工作,让笔记本电脑试试这个,因为它看起来很棒。。。在我的周末开始之前
@model Derived1
@Html.EditorFor(x => x.Derived1Property)
@model Derived2
@Html.EditorFor(x => x.Derived2Property)
public class BaseClassModelBinder : 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;
    }
}
ModelBinders.Binders.Add(typeof(BaseClass), new BaseClassModelBinder());