验证域模型:如何以及在何处

Bob*_*y B 5 validation asp.net-mvc entity-framework asp.net-mvc-4 entity-framework-5

典型的EF + MVC系统将具有两个或三个验证级别:

  1. 对于ViewModel:输入/物理验证(DataAnnotations,FluentValidation),换句话说,长度,空值,范围,正则表达式等。
  2. 对于模型:输入/物理验证(如果不使用MVC且数据来自另一个系统,WCF,表单等,则重复1)
  3. 对于模型:逻辑/“业务规则”验证

我找不到针对实际模型/实体/域/“业务规则”进行2 + 3验证的最佳实践。我们要么:

  • 将简单的验证规则放在实体的属性设置器中(但这确实很麻烦)
  • 挂钩到EF SaveChanges(),如果实体处于AddedModified状态,则触发验证(一次验证整个实体)

这很难维持。ViewModel验证有很多想法,但是对于Model验证,它是特定于领域的,因此您需要确定一个有创意的解决方案,而我的解决方案并不是那么好。

  • 是否有更好的方法或有用的工具(例如DataAnnotations或FluentValidation,但适用于域实体)?
  • 进行模型验证或触发模型验证的最佳位置在哪里?

Eri*_*sch 6

一个典型的MVC + EF系统将具有3层,但这并不是您要说的。

  1. 表示层(输入/输出)
  2. 业务层(逻辑层)
  3. 数据层(模型代表底层数据)

MVC为第1层提供验证。EF为第3层提供验证。MVC或EF没有为第2层提供验证功能。如果要在那里进行验证,则必须自己进行验证,或使用第三方业务对象框架。

第1层和第3层的验证是分开的,即使在许多情况下它们可能具有相似的验证。原因是验证以不同的方式和不同的要求完成。

例如,由于数据建模或业务逻辑原因,您的数据库中可能有一个可为空的字段(假设某些数据已预先加载,并且需要用户在业务流程中更新该字段)。数据层说它可以为空,但是您希望您的UI使其成为必需。

编辑:

简而言之,数据模型不应强制执行业务规则。因此,除了要针对物理数据模型进行验证之外,您不需要在数据模型中进行任何验证(即,如果字段为可空值,则模型中的数据类型应该为可空值,否则就不需要)。在大多数情况下,从代码模型的角度来看,您实际上不能插入无效的数据(从数据模型的角度来看),因为代码模型不允许这样做。唯一的例外是字符串变量,它显然会溢出物理模型的大小约束,但是如果发生这种情况,无论如何都会引发异常。

您的中间层(业务层)应该是您需要验证业务规则的位置(例如,客户采购订单必须以字母开头)。MVC或实体框架,WCF或任何其他方法都无法提供进行此验证的任何方法。

这里有些脱节,因为业务规则应该(理论上)应该驱动表示层的验证。但是,MVC没有内置功能可以做到这一点。因此,您最终在UI中复制了业务规则。

至少有一个第三方业务对象框架试图对此进行处理。CSLA。他们提供了一个自定义的MVC模型绑定程序,该绑定程序将业务对象与UI绑定在一起进行验证,但这只是使用MVC的内置可扩展性来完成。

因此,如果您不想使用专用的业务对象框架,则会陷入在UI和业务层之间重复验证的麻烦,或者试图找出自己的方式来进行自己的业务层控件UI验证。