3

使用新的 ASP.NET MVC 2 验证功能,我们可以使用DataAnnotations描述有效值标准的属性来装饰域模型对象的属性。DefaultModelBinder知道这一点并在ModelState.IsValid调用控制器操作之前相应地填充。由于验证规则是在域模型中定义的,因此这被视为模型级别的验证。斯科特·格思里写道

在我们的 Person 对象中实现规则的好处是,这将确保验证将通过我们应用程序中使用 Person 对象的任何场景 [...]

严格来说,我认为这些规则并没有真正执行,因为所有操作方法都需要检查ModelState.IsValid属性并根据其值采取不同的行动。此外,虽然规则是在模型中定义的,但它们在表示层中应用,因为这是所有模型绑定器所在的地方。但我想这只是我对单词的选择很挑剔(或者我完全错了)。

但是,如何在域模型级别执行验证规则呢?Steven Sanderson 在一篇关于 xVal 验证框架的文章中使用了这种方法,他写道:

现在,模型层通过拒绝放置不符合所有验证和业务规则的预订来强制执行其自身的有效性。

在他的示例中,“预订管理器”(位于模型中)在使用代码尝试进行无效预订时抛出一个特殊的业务规则异常。因此,消费代码不可能进行无效预订,无论它是否事先检查了预订的有效性(通过ModelState.IsValid或其他一些自定义构造)。

所以我的问题是:

假设在模型级别定义了验证规则,它们是否也应该在模型中强制执行?

(请注意,我对领域驱动设计的概念真的很陌生,所以如果我没有使用正确的术语,请多多包涵。)

4

3 回答 3

1

假设在模型级别定义了验证规则,它们是否也应该在模型中强制执行?

是的。如果你提供了一种让规则短路的方法,那么它们就会短路。也许不是你,也许不会很快,但肯定会在未来 x 周/月/年由其他开发人员完成。

此外,总是存在人为错误因素——也许有一天当你累了或在深夜编码时,你错误地读取了这个验证标志,实际上让那些没有验证的记录通过。(不要嘲笑,我自己做过!)

我现在总是确保一条记录在未经模型验证的情况下无法进入数据库。

于 2010-02-12T15:26:56.700 回答
0

我也不太确定这个 DataAnnotations。但似乎它们应该在任何地方工作,无论模型是否在 ASP.NET MVC 项目中并从那里使用。因为 DataAnnotations 是 System.ComponentModel.DataAnnotations 的一部分。我发现这特别有用,因为我的所有模型都在单独的项目中定义,在我的 VS 解决方案的核心 MVC 项目之外。

于 2010-02-13T18:09:30.067 回答
0

DataAnnotations 是 ASP.NET MVC 2 的一个有用功能,它确实提供了一种很好的廉价方式来获得服务器端和客户端验证。不过,您指出一个主要弱点是对的。但我也不认为通过模型强制验证是肯定的。我看到两个问题:

问题 1:您如何执行此操作?您可以对构造函数和设置器等进行各种验证,但您很容易遇到需要规避这些规则的问题。一个很好的例子是序列化;虽然您通常可以解决它,但有时在对象的反序列化期间,您只需要让对象处于无效状态片刻。另一个例子只是一个极其复杂的层次模型(例如,父母需要一个孩子,而那个孩子需要一个父母,显然你有一个先有鸡还是先有蛋的问题,因为你不能同时构建它们)。

问题 2:更高级别的验证规则如何(例如,用户名必须是唯一的)?您不能在模型中拥有这些规则。

归根结底,您应该努力使您的代码尽可能干净和意图揭示,并保持良好的测试。我还没有看到任何基于模型的验证能够真正 100% 地完全保护数据的完整性。即使用户没有破坏您的模型,另一个开发人员最终也会这样做。

于 2010-02-15T05:49:13.257 回答