5

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

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

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

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

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

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

1 回答 1

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 验证。

于 2012-10-11T06:13:37.950 回答