2013-12-16 122 views
2

来自业务层和视图模型的DDD域模型是不同的物质。视图模型表示来自域模型的一些部分。DDD ASP MVC验证最佳实践

在ASP MVC DataAnnotations和Fluent验证库通常用作验证机制。

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

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

P.S.我们可以通过在Controller方法中从域模型更新ModelState来手动应用控制器中的验证。但是它会进行两次验证调用(一个是查看模型,另一个是域模型)。可能有一个简单的可能性,在ASP.NET MVC Server Engine中关闭View Model验证,同时使用JS客户端验证。

回答

3

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

想一想这个比喻:如果一个身体不吃东西,它就会死亡。如果用户实体没有firstName,则会引发异常。

那么谁应该做验证?谁应该正确地知道域名需要什么?我的答案是域之前的层,这是你的情况下控制器

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

服务层

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

服务层+验证

在验证的情况下,业务层应该充当“路障”,以保护您的域名从进入无效状态。这是您进行“域特定”验证的地方。

服务层强制执行Single-Responsiblity-Principle,而不是多个控制器或多个操作方法与同一个实体进行交互。

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

More about service layer

Tutorial about service layer

Sample implementation of the service layer with Unit Testing

如果您担心在这两个业务层和表现层(有数据注释),具有验证,读https://stackoverflow.com/a/8075115/1027250

0

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

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