ASP.NET MVC 2自定义模型绑定问题

时间:2010-10-18 20:16:17

标签: asp.net-mvc model-binding

背景

我有一个付款页面,用户可以从现有付款方式列表中进行选择,也可以指定一个新付款方式。下拉列表提供了以下选项:

  1. 签证 - * **** * 1234(已保存)
  2. 万事达卡 - * **** * 9876(已保存)
  3. [新信用卡...]
  4. [新电子支票...]
  5. 使用jQuery,我切换隐藏的DIV,其中包含信息表(对于保存的付款方式,在选项1或2的情况下)或表单(在[new]选项的情况下)。

    我使用强类型类作为我的视图模型,其中包含(在简单类型中)CreditCard类和Check类。这些类中的每一个都使用数据注释验证器,因为它们在站点的其他部分中使用。

    问题

    当用户提交表单时会出现问题。我想使用模型绑定来处理POST值的映射,但我需要根据用户选择的选项来触发绑定和/或验证。例如,如果用户从上面的列表中选择选项1或2,我不希望为CreditCard或Check对象触发模型验证(或甚至绑定本身)。

    我研究了使用IModelBinder创建自定义模型绑定器的可能性,以及扩展DefaultModelBinder并覆盖某些方法。但是,我不确定哪种方法更好,并且,如果扩展DefaultModelBinder,这将是适当的方法来覆盖。

    逻辑很简单:

    • 如果用户选择了一种现有付款方式,则无需对CreditCard或Check进行验证。
    • 如果用户选择了其中一个选项来创建新的付款方式,则只需要绑定和验证所选方法(CreditCard或Check)

    感觉好像扩展DefaultModelBinder是要走的路,因为我希望框架可以完成大部分繁重工作,而无需从头开始创建自定义绑定器。但是,在查看可用的覆盖方法时,不清楚哪个是最好的方法:

    1. BindProperty - 这里的问题是我基本上需要查看其中一个属性来确定应该绑定哪些其他属性。我认为我无法控制传入属性的绑定顺序,我也不想依赖它们在HTML表单中设置的顺序。
    2. OnModelUpdated - 到目前为止,为时已晚。已触发数据注释的绑定验证,并且已更新ModelState。我必须循环遍历ModelState并删除不相关的错误。
    3. OnPropertyValidating - 起初我认为这是我应该看的地方,但即使为所有属性(作为测试)返回TRUE也会导致ModelState包含绑定错误。
    4. 我在应用程序的其他方面遇到过这种情况,并决定将功能拆分为单独的控制器/操作以简化流程。但是,我希望更好地了解如何处理更复杂的UI问题,尤其是与MVC模型绑定功能相关的问题。

      非常感谢有关此主题的任何帮助。

      所有可能的值都存储在下拉列表中。使用jQuery,我切换表单(对于新的付款方式)和显示(对于现有方法)

2 个答案:

答案 0 :(得分:1)

我决定尝试完全绕过模型绑定,并在我的控制器操作中使用FormCollection,IValueProvider和TryUpdateModel。

答案 1 :(得分:0)

您的问题听起来专门用于放置在默认的ModelBinder中。

ModelBinder就是这个诱惑者,它假装她可以解决你所有的问题。但是你开始将ModelState合并在一起,然后开始用嵌套对象列表做疯狂的事情,在你知道它之前,她会用离婚文件给你打电话,除了你的骨头之外别无他法。

MVC 3承诺提供更具扩展性的ModelBinder,但是根据我自己的个人经验,除非你需要更改它的超级简单,例如空的texbox变为“”而不是null,而不是远离你自己的实现。

另一种方法是逐步使用现有的ModelBinder功能,并使用忽略方法参数等方法来清理:

if( myModel.IsNewPayment )
   UpdateModel( myModel.Payment, "exclude everything else" );

你提出的很多关于模型绑定器的建议实际上也是业务逻辑,应该在另一层。我用自己的ModelBinder完成了一些疯狂的事情,现在后悔我在那里编写的每一行代码。也许它只是我,但你真的在弯曲规则,并通过将业务和支付逻辑放在那里完全诋毁“单一责任主体”。