【发布时间】:2011-01-17 10:16:05
【问题描述】:
我有我认为有点正常的情况,我需要将表单帖子绑定到“订单”模型。这个模型有几个层次的信息:
Order.Billing.FirstName
Order.Billing.Address.City
Order.Billing.Address.Country
使用 DefaultModelBinder,如果我将表单发布到以该 Order 模型作为参数的操作,则以下字段 JustWork(TM):
<%=Html.TextBox("Billing.FirstName")%>
<%=Html.TextBox("Billing.Address.City")%>
该字段没有:
<%=Html.TextBox("Billing.Address.Country")%>
我的问题在于乡村财产。在我们的例子中,Address.Country 返回一个 Country 类实例(ISO2/3/Name/Code 逻辑)。它不是一个字符串。默认情况下它不起作用也就不足为奇了。
我的第一个想法是创建一个 CountryModelBinder(继承 DefaultModelBinder)和 ModelBinders.Binders。将其添加到 Country 的类型中。当我这样做时,CountryModelBinder 永远不会在上面的场景中被调用。
我的第二个想法是创建一个 AddressModelBinder(继承 DefaultModelBinder)并将其绑定到我们的 Address 类型。虽然确实会调用它,但“Country”的 SetProperty 调用有一个空值,即使表单已发布了一个名为“Billing.Address.Country”的字段。
经过一些修改,模型绑定行为似乎仅在模型是操作所需的顶级类时才调用 CreateModel,并且所有其他绑定器的 BindPropery/SetProperty 都为子属性调用。
换句话说,如果我为 Order、OrderAddress(Billing)、Address 和 Country 创建模型绑定器。对于接受订单的操作,仅调用 OrderModelBinder.CreateModel。某些事情会调用 ORderAddress 和 Address.BindProperty/SetProperty,有时 SetProperty 值参数在明确以与其他字段属性映射匹配的名称发布时为空。
只需向 OrderModelBinder 添加代码即可将 Billing.Address.Country 从 Request.Form 中拉出,这很容易。但是我有多个使用 Address 的模型,并且让所有模型都这样做似乎很糟糕。
我在这里缺少什么?在这种情况下,有没有办法让 CountryModelBinder 真正被调用?我认为当 Billing.Address.Country 映射到地址绑定器的 Country 属性时,应该调用 CountryModelBinder。
【问题讨论】:
-
我在嵌套模型结构中遇到了同样的问题,在我看来,顶层和下一层的属性正在受到约束,但任何低于此的属性似乎都被忽略了。这是模型绑定器的正常行为吗?似乎相当随意的行为。
标签: asp.net-mvc nested modelbinders defaultmodelbinder