cla*_*aco 7 asp.net-mvc nested defaultmodelbinder modelbinders
我有我认为是一种有点正常的情况,我需要将表单帖子绑定到"订单"模型.该模型具有以下几个级别的信息:
Order.Billing.FirstName
Order.Billing.Address.City
Order.Billing.Address.Country
Run Code Online (Sandbox Code Playgroud)
使用DefaultModelBinder,如果我将表单发布到将此Order模型作为参数的操作,则以下字段为JustWork(TM):
<%=Html.TextBox("Billing.FirstName")%>
<%=Html.TextBox("Billing.Address.City")%>
Run Code Online (Sandbox Code Playgroud)
此字段不会:
<%=Html.TextBox("Billing.Address.Country")%>
Run Code Online (Sandbox Code Playgroud)
我的皱纹是乡村财产.在我们的例子中,Address.Country返回一个Country类实例(ISO2/3/Name/Code逻辑).它不是一个字符串.毫不奇怪它默认不起作用.
我的第一个想法是创建一个CountryModelBinder(继承DefaultModelBinder)和ModelBinders.Binders.将它添加到Country的类型.当我这样做时,CountryModelBinder永远不会在上面的场景中被调用.
我的第二个想法是创建一个AddressModelBinder(继承DefaultModelBinder)并将其绑定到我们的Address类型.虽然它被调用,但SetProperty对"Country"的调用具有空值,即使表单已发布名为"Billing.Address.Country"的字段.
一些修修补补之后,看来当模型的顶层类动作的人,而其他所有的粘合剂都要求孩子自己的属性BindPropery /的SetProperty模型绑定行为只要求CreateModel.
换句话说,如果我为Order,OrderAddress(Billing),Address和Country创建模型绑定器.对于接受订单的操作,仅调用OrderModelBinder.CreateModel.ORderAddress和Address.BindProperty/SetProperty被调用用于某些事情,有时SetProperty值参数是空的,当它明确地张贴在与其他字段属性映射匹配的名称中时.
只需向OrderModelBinder添加代码就可以将Billing.Address.Country拉出Request.Form.但是我有多个使用Address的模型,并且所有这些模型看起来都很糟糕.
我在这里错过了什么?有没有办法在这种情况下实际调用CountryModelBinder?我认为当Billing.Address.Country映射到Address绑定器的Country属性时,应该调用CountryModelBinder.
我已经尝试做你在这里所做的事情,看来在 MVC3 上,如果我为该类型提供模型绑定器,它确实可以工作。
这只是一个概念证明,表明它确实有效,不应该被视为接近生产级别代码:
楷模:
public class SimpleModel
{
public string Value { get; set; }
public int Other { get; set; }
}
public class ComplexModel
{
public SimpleModel Complexity {get;set;}
public string StrVal { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
一些粘合剂:
public class MBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if ( bindingContext.ModelType == typeof(SimpleModel))
{
var simpleModel= new SimpleModel();
simpleModel.Other = 1;
simpleModel.Value = controllerContext.HttpContext.Request.Form["Complexity"];
return cm;
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
在全球 asax 中:
ModelBinders.Binders.Add(typeof (SimpleModel), new MBinder());
Run Code Online (Sandbox Code Playgroud)
视图中的代码:
@model ComplexModel
@using ( Html.BeginForm() )
{
<fieldset>
@Html.LabelFor(x => x.Complexity)
@Html.TextBoxFor(x => x.Complexity)
</fieldset>
<fieldset>
@Html.LabelFor(x => x.StrVal)
<br />
@Html.EditorFor(x => x.StrVal)
</fieldset>
<input type="submit" />
}
Run Code Online (Sandbox Code Playgroud)
控制器:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(ComplexModel model)
{
return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,在 MVC 3 中,更好的选择是使用 IModelBinderProvider 接口,但我只是想展示一些可行的东西。
| 归档时间: |
|
| 查看次数: |
905 次 |
| 最近记录: |