【问题标题】:DDD ASP MVC validation best practicesDDD ASP MVC 验证最佳实践
【发布时间】:2014-01-03 10:58:56
【问题描述】:

在 DDD 中,业务层的领域模型和视图模型是不同的实体。而 View Model 代表了 Domain Model 的一些部分。

在 ASP MVC 中,通常使用 DataAnnotations 和 Fluent Validation Library 作为验证机制。

在域模型和视图模型之间共享验证的最佳实践是什么?

我不喜欢为每个属性创建自定义验证属性的变体。

附:我们可以通过在控制器方法中从域模型更新 ModelState 来手动在控制器中应用验证。但这将是两次验证调用(一次通过视图模型,一次通过域模型)。可能有一个简单的可能性来关闭 ASP.NET MVC 服务器引擎中的视图模型验证,同时使用 JS 客户端验证。

【问题讨论】:

    标签: c# asp.net-mvc validation


    【解决方案1】:

    虽然有一个学校声明"A domain entity should always be valid"。简而言之,实体不应该包含验证,而是通过检查自身然后抛出异常来强制执行“特定于域”的要求。有些人可能不同意这一点,但这是另一个话题。

    考虑这个类比:如果一个身体不吃东西,它就会死。如果用户实体没有名字,则会引发异常。

    那么谁应该进行验证?谁应该正确地知道域需要什么?我的答案是域之前的层,在你的例子中是 Controller

    如果您担心跨多个控制器或跨多个操作方法进行重复验证,那么您应该考虑添加另一个名为“服务层”

    的层

    服务层

    这个服务层的目的是封装(保护)你的领域模型。你可能认为这是你的控制器,但他们实际上有不同的职责。对于小型项目,服务层和控制器可以合二为一。

    服务层+验证

    在验证的上下文中,服务层应充当“路障”,以保护您的域免于进入无效状态。这是您进行“特定领域”验证的地方。

    服务层执行单一职责原则,而不是多个控制器或多个操作方法与同一实体交互。

    服务层还使您能够添加可测试性。

    More about service layer

    Tutorial about service layer

    Sample implementation of the service layer with Unit Testing

    如果您担心在服务层和表示层都进行验证(使用数据注释),请阅读https://stackoverflow.com/a/8075115/1027250

    【讨论】:

      【解决方案2】:

      您不应该共享域和视图验证,它们应该是单独的层,并且这些层中的验证应该适用于不同的问题。

      • 使用 ViewModel DataAnnotations 或 FluentValidation 在 ViewModel 和 Controller 中验证用户输入,最好启用客户端验证
      • 使用自定义验证验证 DomainModel 和服务/业务层中的业务/域规则
      • 如果您的服务层为不同的消费者提供功能,则可能需要一些冗余的输入验证

      【讨论】:

        猜你喜欢
        • 2023-03-12
        • 1970-01-01
        • 2015-10-20
        • 1970-01-01
        • 1970-01-01
        • 2013-10-06
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        相关资源
        最近更新 更多