【问题标题】:MVC, ViewModels, and ValidationMVC、视图模型和验证
【发布时间】:2011-06-01 19:54:21
【问题描述】:

我正在使用 POCO 使用 EF4 创建 MVC3 应用程序。我已向我的 EF 实体添加了验证属性。现在,当我构建视图时,我想使用视图模型(并且可能使用AutoMapper 来填充它们)。

我遇到的问题是我必须在我的视图模型上重新定义我的验证属性,这违反了 DRY 原则。例如,如果我决定更改字段的大小,我必须同时更改 POCO 和使用它的任何视图模型的 MaxLength 属性。

是否有一些技巧可以将验证规则从我的 POCO 映射到我的视图模型?

【问题讨论】:

    标签: .net asp.net-mvc-3 poco ef4-code-only


    【解决方案1】:

    我个人在视图模型上执行验证。这是控制器从视图接收的内容,它是包含用户输入的类。我区分了两种类型的验证规则:表面验证和业务验证。诸如必填字段、正确格式之类的规则应在视图模型中强制执行,而诸如数据库中已存在具有给定名称的用户之类的业务规则应在模型上进行验证。

    您也可以将不同的视图模型映射到同一个模型,但基于视图验证规则可能会有所不同。因此,您不会在视图模型上拥有完全相同的验证规则。

    【讨论】:

      【解决方案2】:

      获得一些抽象的一种方法是让您的业务模型类“组合”一个 ViewModel,包括您需要的其他视图信息。

      class MyObject 
      {
          public int ID {get;set}
      
          [Required]
          [StringLength(512)]     
          public string Name {get;set;}
      
      }
      
      class MyViewModel // ViewModel for a specific view 
      {
          public MyObject MyModel {get;set;}        // the model that is being edited 
      
          // other data the view might need, set by the controller 
          public string SomeMessage { get; set; }
          public List<SomeObject> SomeObjects {get;set;} /// e.g. for a drop-down list
      
      }
      

      然后在视图中相应地引用 ViewModel。

      @model My.Namespace.MyViewModel
      
      
      Hello @model.MyModel.Name !!!
      

      这样,您只需在一个位置指定业务类中的验证和/或数据注释。

      如果您想要进行不同的验证,那么这将需要一些策略来选择性地应用验证逻辑。

      【讨论】:

        【解决方案3】:

        我也对此感到困惑,并且我同意它违反了 DRY。我最近发布了一个关于此Here 的问题,但遭到了相当多的反对。

        在任何现实世界的应用程序中,您都无法获得完美的 DRY。有时,你从违反原则中得到的好处比试图盲目地坚持要好。

        编辑:

        人们也可能认为 DRY 可能违反单一职责原则 (SRP)。通过重用类似的代码,您现在正在使代码做不止一件事。如果您考虑到数据模型和视图模型具有不同的目的,因此具有不同的职责这一事实......将它们组合成一个模型违反了 SRP。也就是说,通过使您的数据模型也成为视图模型,这是两个不同的职责。

        现在,在这方面,人们可以想出多种方法来尝试协调 SRP 与 DRY,但在某些时候,您必须权衡成本带来的好处。

        【讨论】:

        • 感谢您的回复。我仍然希望有一些聪明的方法可以重用我的验证属性进行 JQuery 验证(我不太关心控制器中的验证,实体对象会很好),但现在我只是重新-实现我想要的属性。
        猜你喜欢
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多