Asp.net mvc 嵌套级别的DefaultModelBinder问题+;其他粘合剂
我认为这是一种正常情况,需要将表单帖子绑定到“订单”模型。此模型有几个层次的信息:Asp.net mvc 嵌套级别的DefaultModelBinder问题+;其他粘合剂,asp.net-mvc,nested,modelbinders,defaultmodelbinder,Asp.net Mvc,Nested,Modelbinders,Defaultmodelbinder,我认为这是一种正常情况,需要将表单帖子绑定到“订单”模型。此模型有几个层次的信息: Order.Billing.FirstName Order.Billing.Address.City Order.Billing.Address.Country 使用DefaultModelBinder,如果我将表单发布到将此订单模型作为参数的操作,则以下字段JustWork(TM): 此字段不包括: <%=Html.TextBox("Billing.Address.Country")%>
Order.Billing.FirstName
Order.Billing.Address.City
Order.Billing.Address.Country
使用DefaultModelBinder,如果我将表单发布到将此订单模型作为参数的操作,则以下字段JustWork(TM):
此字段不包括:
<%=Html.TextBox("Billing.Address.Country")%>
我遇到的麻烦是乡村财产。在我们的例子中,Address.Country返回一个Country类实例(ISO2/3/Name/Code逻辑)。它不是一根弦。它在默认情况下不起作用也就不足为奇了
我的第一个想法是创建CountryModelBinder(继承DefaultModelBinder)和ModelBinders.Binders.Add,将其添加到Country类型中。当我这么做的时候,CountryModelBinder从来没有在上面的场景中被调用过
我的第二个想法是创建AddressModelBinder(继承DefaultModelBinder)并将其绑定到我们的地址类型。虽然它确实被调用,但是“Country”的SetProperty调用有一个空值,即使表单已经发布了一个名为“Billing.Address.Country”的字段
经过一些修补之后,似乎只有当模型是操作所需的顶级类时,模型绑定行为才会调用CreateModel,并且所有其他绑定都会为子属性调用其BindProperty/SetProperty
换句话说,如果我为订单、订单地址(账单)、地址和国家创建模型绑定器。对于接受订单的操作,仅调用OrderModelBinder.CreateModel。ORderAddress和Address.BindProperty/SetProperty在某些情况下被调用,有时SetProperty值参数在与其他字段属性映射匹配的名称中明确发布时为空
只需将代码添加到OrderModelBinder中,即可将Billing.Address.Country从Request.Form中拉出。但我有多个使用地址的模型,让所有的模型都使用地址,这似乎是不正确的
我错过了什么?在这种情况下,有没有办法让CountryModelBinder真正被调用?我认为,当Billing.Address.Country映射到地址绑定器的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; }
}
一些活页夹:
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;
}
}
在全球asax中:
ModelBinders.Binders.Add(typeof (SimpleModel), new MBinder());
视图中的代码:
@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" />
}
顺便说一句,在MVC 3中,更好的选择是使用IModelBinderProvider接口,但我只是想展示一些有用的东西。这可能会帮助您:我对嵌套模型结构也有同样的问题,在我看来,顶层和底层的属性都受到约束,但任何低于这个标准的东西似乎都会被忽视。这是模型绑定器的正常行为吗?这似乎是相当武断的行为。
@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" />
}
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(ComplexModel model)
{
return RedirectToAction("Index");
}