DDD ASP MVC验证最佳实践

时间:2013-12-16 05:57:03

标签: c# asp.net-mvc validation

在DDD中,来自业务层和视图模型的域模型是不同的物质。 View Model代表Domain Model的一些部分。

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

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

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

P.S。我们可以通过在Controller方法中从Domain Model更新ModelState来手动在控制器中应用验证。但它将是两次验证调用(一个是View Model,另一个是Domain Model)。可能很有可能在ASP.NET MVC Server Engine中关闭View Model验证,同时使用JS客户端验证。

2 个答案:

答案 0 :(得分:3)

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

考虑这个比喻:如果一个人不吃东西,它就会死亡。如果User实体没有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

答案 1 :(得分:1)

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

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