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

时间:2012-10-11 05:39:02

标签: asp.net-mvc entity-framework validation asp.net-mvc-4 entity-framework-5

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

  1. 对于ViewModel:输入/物理验证(DataAnnotations,FluentValidation),换句话说,长度,空值,范围,正则表达式等。
  2. 对于模型:输入/物理验证(如果未使用MVC且数据来自另一个系统,WCF,表格等,则重复1次)
  3. 对于模型:逻辑/“业务规则”验证
  4. 我无法找到实际Model / entities / domain /“业务规则”验证2 + 3的最佳做法。我们要么:

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

    这很难维护。很多想法都进入了ViewModel验证,但是对于模型验证,它是特定于域的,因此您可以确定一个创造性的解决方案,而我的解决方案并不是很好。

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

1 个答案:

答案 0 :(得分:5)

典型的MVC + EF系统将有3层,但它们并不是你所说的。

  1. 表示层(输入/输出)
  2. 业务层(逻辑层)
  3. 数据层(模型代表低级数据)
  4. MVC为第1层提供验证.EF为第3层提供验证.MVC或EF不为第2层提供验证功能。如果要在那里进行验证,则必须自己进行验证,或使用第三方业务对象框架。

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

    例如,您可能在数据库中有一个可以为数据建模或业务逻辑原因而为空的字段(假设某些数据已预先加载,并且用户需要在业务流程中更新该字段)。数据层表示它可以为空,但您希望UI能够满足要求。

    编辑:

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

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

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

    至少有一个第三方业务对象框架试图解决这个问题。 CSLA。它们提供了一个自定义的MVC模型绑定器,它将业务对象与UI绑定在一起进行验证,但这只是使用MVC的内置扩展性来实现这一点。

    因此,如果您不想使用专用的业务对象框架,则要么在UI和Business层之间复制验证,要么试图找出自己的方式来进行自己的业务层控制UI验证。 / p>