【问题标题】:mvc3 razor editortemplate with abstract classes带有抽象类的 mvc3 剃须刀编辑器模板
【发布时间】:2012-05-12 01:15:03
【问题描述】:

这是来自MVC3 Razor httppost return complex objects child collections 的后续问题。

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

我为每个派生类创建了一个模板,并尝试使用 if child is of type 然后将模板名称作为字符串提供。模板被渲染到视图中,但不会在回帖中填充。

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

【问题讨论】:

    标签: asp.net-mvc-3 razor mvc-editor-templates


    【解决方案1】:

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

    型号:

    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; }
    }
    

    控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new MyViewModel
            {
                Children = new BaseClass[]
                {
                    new Derived1 { Id = 1, Derived1Property = "prop1" },
                    new Derived2 { Id = 2, Derived2Property = "prop2" },
                }
            };
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(MyViewModel model)
        {
            // everything will be fine and dandy here
            ...
        }
    }
    

    查看(~/Views/Home/Index.cshtml):

    @model MyViewModel
    
    @using (Html.BeginForm())
    {
        for (int i = 0; i < Model.Children.Count; i++)
        {
            @Html.EditorFor(x => x.Children[i].ModelType)
            <div>
                @Html.EditorFor(x => x.Children[i].Id)
                @Html.EditorFor(x => x.Children[i])    
            </div>
        }
    
        <button type="submit">OK</button>
    }
    

    Dervied1 类型 (~/Views/Home/EditorTemplates/Derived1.cshtml) 的编辑器模板:

    @model Derived1
    @Html.EditorFor(x => x.Derived1Property)
    

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

    @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;
        }
    }
    

    将在Application_Start注册:

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

    【讨论】:

    • 太棒了...这真是一种享受...我不得不回去工作并拿笔记本电脑尝试一下,因为它看起来很棒...在它开始之前就度过了我的周末跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多