Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NET MVC 2自定义模型绑定问题_Asp.net Mvc_Model Binding - Fatal编程技术网

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

Asp.net mvc ASP.NET MVC 2自定义模型绑定问题,asp.net-mvc,model-binding,Asp.net Mvc,Model Binding,背景 我有一个付款页面,用户可以从现有付款方式列表中进行选择,或指定新的付款方式。下拉列表显示以下选项: Visa-*******1234(已保存) 万事达卡-*******9876(已保存) [新信用卡…] [新电子支票…] 使用jQuery,我切换隐藏的div,这些div包含一个信息表(对于保存的付款方法,是选项1或2)或一个表单(对于[new]选项) 我使用一个强类型类作为我的视图模型,它包含(在简单类型中)一个CreditCard类和一个Check类。这些类中的每一个都使用数据注释验证器

背景

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

  • Visa-*******1234(已保存)
  • 万事达卡-*******9876(已保存)
  • [新信用卡…]
  • [新电子支票…]
  • 使用jQuery,我切换隐藏的div,这些div包含一个信息表(对于保存的付款方法,是选项1或2)或一个表单(对于[new]选项)

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

    问题

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

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

    逻辑相当简单:

    • 如果用户选择了现有的付款方式之一,则不需要对信用卡或支票进行验证
    • 如果用户选择其中一个选项来创建新的付款方式,则只需要绑定和验证所选的方式(信用卡或支票)
    感觉扩展DefaultModelBinder是一条必由之路,因为我希望大部分繁重的工作都由框架完成,而无需从头开始创建自定义绑定。但是,在查看可用的重写方法时,不清楚哪种方法是最好的:

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

    在此问题上的任何帮助都将不胜感激


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

    您的问题听起来很专业,可以放在默认的ModelBinder中

    ModelBinder是一个诱惑者,以她能解决你所有的问题为借口引诱你。但是你开始把ModelState合并在一起,然后开始用嵌套对象列表做一些疯狂的事情,在你意识到之前,她用离婚文件扇你耳光,拿走除了你的骨头以外的所有东西

    MVC 3承诺提供更具可扩展性的ModelBinder,但根据我个人的经验,除非您需要更改的内容非常简单,例如空文本框变为“”而不是null,而不是远离您自己的实现

    另一种方法是零碎地使用现有的ModelBinder功能,并使用诸如忽略方法参数之类的方法来清理:

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

    您提议填充到模型绑定器中的很多内容实际上也是业务逻辑,应该放在另一层中。我用自己的ModelBinder做了一些疯狂的事情,现在我后悔在那里写的每一行代码。也许只是我,但你真的违反了规则,将业务和支付逻辑放在了“单一责任原则”中,彻底破坏了它。

    你的问题听起来很专业,可以放在默认的ModelBinder中

    ModelBinder是一个诱惑者,以她能解决你所有的问题为借口引诱你。但是你开始把ModelState合并在一起,然后开始用嵌套对象列表做一些疯狂的事情,在你意识到之前,她用离婚文件扇你耳光,拿走除了你的骨头以外的所有东西

    MVC 3承诺提供更具可扩展性的ModelBinder,但根据我个人的经验,除非您需要更改的内容非常简单,例如空文本框变为“”而不是null,而不是远离您自己的实现

    另一种方法是零碎地使用现有的ModelBinder功能,并使用诸如忽略方法参数之类的方法来清理:

    if( myModel.IsNewPayment )
       UpdateModel( myModel.Payment, "exclude everything else" );
    
    您提议填充到模型绑定器中的很多内容实际上也是业务逻辑,应该放在另一层中。我用自己的ModelBinder做了一些疯狂的事情,现在我后悔在那里写的每一行代码。也许只有我一个人,但你真的违反了规则,把业务和支付逻辑放在了这里,彻底破坏了“单一责任原则”。

    我决定