Jon*_*Jon 5 mvc-editor-templates razor asp.net-mvc-3
这是MVC3 Razor httppost返回复杂对象子集合的后续问题.
我给出的例子非常简单.子集合实际上是一个对象集合,它们都来自抽象基类.所以集合有一个基类列表.
我已经为每个派生类创建了一个模板,并尝试使用if子类型,然后将模板名称作为字符串.模板将呈现给视图,但不会在帖子后面填充.
我不确定如何使用编辑器对模板进行选择正确的模板,并将信息编组回父容器中的子对象.
您可以使用自定义模型绑定器.我们来举个例子吧.
模型:
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; }
}
Run Code Online (Sandbox Code Playgroud)
控制器:
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
...
}
}
Run Code Online (Sandbox Code Playgroud)
查看(~/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>
}
Run Code Online (Sandbox Code Playgroud)
Dervied1
type(~/Views/Home/EditorTemplates/Derived1.cshtml
)的编辑器模板:
@model Derived1
@Html.EditorFor(x => x.Derived1Property)
Run Code Online (Sandbox Code Playgroud)
和Dervied2
type(~/Views/Home/EditorTemplates/Derived2.cshtml
)的编辑器模板:
@model Derived2
@Html.EditorFor(x => x.Derived2Property)
Run Code Online (Sandbox Code Playgroud)
现在剩下的就是一个自定义模型绑定器,它将使用隐藏字段值来实例化集合中的正确类型:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
将在以下地址注册Application_Start
:
ModelBinders.Binders.Add(typeof(BaseClass), new BaseClassModelBinder());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2270 次 |
最近记录: |