【问题标题】:Validation of domain model: how and where域模型的验证:如何和在哪里
【发布时间】:2012-10-01 17:23:03
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 我不明白你的“水平”。 “物理验证”是什么意思?我不明白 1 和 2 之间有什么区别。您指的是客户端和服务器端验证吗? MVC 中没有中间的“逻辑层”验证系统,事实上 MVC 并没有为此提供任何功能。但是在数据层有验证,它针对数据模型(不是逻辑模型)进行验证
  • 我的问题与客户端/服务器无关。 1 表示验证输入:空/长度/范围/等。然后 2 是同样的事情,但是如果数据来自 WCF 或另一个系统,那么 1 没有发生,因此您将再次执行输入/物理验证以确保安全。忽略这一切,我真正需要了解的是人们如何为领域做 2+3。
  • 您的前提是错误的,因此您基于该前提提出的问题是错误的。 MVC 不为模型提供任何验证。它只为视图模型提供验证。 EF 为数据模型提供验证。业务层或域模型在 EF 或 MVC 之外,完全由您控制如何进行验证。
  • 我的前提没有错。我特别解释了这与 MVC 无关。我们在 MVC 系统以及非 MVC 系统中使用数据层。我需要知道如何以自动和优雅的方式验证数据层,就像对 MCV 的 ViewModels 所做的那样。
  • 没有什么能阻止您在业务逻辑中使用 FluentValidation。

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


【解决方案1】:

一个典型的 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 验证。

【讨论】:

  • 正如我在上面的评论中提到的,问题不在于 MVC。引入它是为了解释 ViewModels 的 MVC 验证设计得非常好,并且优雅且几乎是自动的。我想为我们的域或 MVC 中的 M 做同样的事情。
  • 我同意你的观点,但问题仍然悬而未决。这很简单:在哪里以及如何物理验证我的实体(格式、可空性等)和逻辑验证我的实体(违反业务规则)的好方法。我解释了我们是如何做到的,这很有效,但并不优雅且难以维护。我想知道其他人是否使用不同的方法。
  • @BobbyB - 我仍然对你想要什么感到困惑。实体代码模型不允许您插入格式错误的内容,不允许您在不可为空的字段中插入空值,不允许您在数字字段中插入字符,不允许您插入无效的日期等。当您设法滑过一些漏洞时(例如,日期精度上溢或下溢),它将引发异常。尝试插入比字段可以包含的字符更多的字符或其他字符也是如此。
  • 再一次,中间业务/域层独立于 MVC 或 EF。该框架没有提供对此进行验证的工具,因此您必须自己进行。
  • 是的,我问的是逻辑业务规则。如果 datetime 是在公共假期,那么生意就关门了,所以只允许下一个工作日,等等。我解释说没有内置的方法可以做到这一点,我的问题是其他人是怎么做的以及在哪里做的。我们在属性设置器中并通过拦截 SaveChanges 来实现。有没有更好的方法或工具。这个问题很简单。
猜你喜欢
  • 2011-07-17
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多