数据注释是用于验证的好方法吗?

12

随着我对ASP.NET MVC的学习越来越深入,我也越来越了解数据注释。
在MVC中,它们被用于验证,这让我有些担忧。
最大的问题是我想尽可能保持我的模型简单干净,作为POCO对象存在。
如果我有那些模型类跨多个项目在一个解决方案中共享(例如:Web前端、桌面应用程序、Web服务),会怎样呢?
基本上我担心特定于我的MVC前端应用程序的注释可能会影响Dynamic Data等其他项目。 我已经将业务对象与数据库模型(在此情况下是LINQ2SQL)分开,所以我不担心注释会对数据访问层产生影响,但我想知道我担心其他项目的恐惧是否合理。

此外,我认为将"必填项"的错误消息绑定到您的模型有点疯狂。

我想,如果我为每个项目(Web、桌面、Web服务等)创建单独的模型,就可以解决问题,但这实际上将是当前共享模型的直接副本。 这是正确的解决方法吗?
这将对我的解决方案产生很大影响(需要进行大量从一个模型到另一个模型的映射)。

你认为怎么样?
我想听听您对数据注释的良好和不良使用的看法。

7个回答

6

我发现数据注释在模型中非常方便,其中规则永远不会因为上下文而改变,例如电子邮件地址。

但是对于更复杂的验证(多个字段,需要访问数据库等),我使用访问者模式,该模式在Entity validation with visitors and extension methods中有描述。


我打算使用你建议的第二个选项——使用访问者模式。我有一个问题,当模型被不同的上下文使用时,我们该如何实现它。一个需要将字符串“客户”作为必填字段进行验证,但在另一个上下文中,“客户”不是必填的。如何处理这种情况。感谢您的帮助。 - Sri Reddy
请参考以下文章了解访问者模式的示例:https://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/ 然后混入类似于 https://www.nuget.org/packages/FluentValidation/ 的内容。 - Todd Smith

3

非常好的问题。特别是因为所有闪亮的演示应用程序都是围绕DataAnnotations处理所有验证构建的,因为它是一个非常好的、闪亮的卖点。而且谁喜欢做验证呢?

我认为更好的方法是将其作为更完整的验证解决方案的一部分,既考虑到你提到的结构性原因,也考虑到它们的局限性——如何使用数据注释验证“这个用户名是否唯一?”或“这个经理是否有权将这个任务分配给这个员工?”等问题。


我知道这是一个五年前的答案,但你能否指点我正确的方向?你说的很有道理,数据注释并不能解决所有问题。 - kazinix
1
@dpp -- 是的,我已经有一段时间没有构建过大型验证了,在这些年里,DataAnnotations 已经变得更好了,其他工具也变得更好了。无论如何,我们的方法是构建一个两阶段验证管道。首先是基于 DataAnnotations 的方法,检查单个对象在内存中可以执行的操作。第二阶段是一个依赖注入的解决方案,它可以将验证与数据库连接起来,查找像唯一性和其他需要查询的约束条件。今天我可能会使用 FluentValidation 作为粘合剂。 - Wyatt Barnett

3

DataAnnotations并不是唯一可用于验证的方法,您可以使用多种验证方法。我在使用DataAnnotations时看到的大多数验证都是专门用于验证将要进入数据库的数据,例如MaxLength()和Range()。

IValidatableObject是我见过的最灵活的自定义验证方法。然而,它并不能解决您拥有一个包含所有对象的单个存储库的具体问题。但是,不用担心!

IDataErrorInfo是另一种您可以验证数据的方法,这可以仅用于您的MVC应用程序,不会影响其他项目。

如果类实现了IDataErrorInfo接口,则ASP.NET MVC框架将在创建该类的实例时使用此接口。因此,您可以使用服务定位器接口或类似的东西来分离您的验证。

然而,我认为IValidatableObject是更好的实现方式。


2

我个人认为DataAnnotations非常适合验证MVC视图模型和输入的数据。但我绝不会在我的业务模型上使用它们。

此外,我对基于属性的验证属性也很偏爱,因为通过反射轻松地发现哪些属性出现在哪里。


0

不确定DataAnnotations是否会影响您的其他项目,但预计它们将忽略DataAnotations,除非您创建一些类来检查它们。

关于尽可能保持POCO简单,DataAnnotations的意图是将元数据和数据放在同一个地方(即如果要求_UnitsInStock始终为正整数,则此要求与“库存单位”的数据定义相关,并完全符合模型的定义)。它还有助于避免一些错误,因为无论您在哪里使用验证(在mvc项目内),规则始终相同(因此您不能忘记在页面A中检查变量的最小值,而在页面B中检查它)。错误消息不是必需的,但您可以使用它来显示更友好的消息,并且此错误消息将在任何地方显示。

它还使得实现自动化服务器和客户端验证(mvc)非常容易。

另一方面,尽管您有能力创建自定义属性来检查业务规则,但与使用“业务类”相比,它需要更多的知识和耐心(如果您不习惯它),据我所知,它仅由mvc 2官方支持。

如果您的模型类在其他项目中共享,那么您可能也有一个共享的验证层,因此请使用该验证层。如果您没有这个验证层,那么DataAnnotations将使您在MVC项目中更加轻松。

0

我认为你不需要担心在多个技术中共享装饰域的问题。DataAnnotations是BCL的一部分,您可以在WCF、WPF、MVC、Web Forms等各种技术中使用它(甚至可能在Silverlight中也可以)。

由于DataAnnotations现在是BCL的核心部分,我们可以期望其他验证框架能够在未来读取这些属性,就像Enterprise Library Validation Application Block 5.0已经做到了一样。这允许稍后使用更复杂的验证扩展模型,而无需更改核心验证规则。

然而,我可以理解您想要保持模型和验证规则的分离。如果这是您想要的,那么验证应用程序块(VAB)可能是一个很好的选择(或者甚至是补充,因为它与DataAnnotations集成)。VAB支持基于配置的验证,这使您可以完全将验证规则与模型分开。

但是,当您的验证规则非常简单时,VAB可能会过度。它非常强大且可扩展,但学习起来也很复杂且耗时。


请问您能否提供一个或多个VBA参考链接? - Steve
您可以开始阅读EntLib Hands-on labs下载包中的Validation instructions CS.pdf,下载链接为:http://bit.ly/gJpVjl(文件夹路径为CS\Validation\instructions)。该文档提供了VAB功能的良好概述。 - Steven

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接