在 .NET Framework 4 中的验证






4.27/5 (7投票s)
.NET Framework 4 中的验证框架
引言
在 .NET Framework 4 中,命名空间System.ComponentModel.DataAnnotations
适用于通用 CLR (WPF) 和更轻量的 Silverlight CLR。 你可以将DataAnnotations
命名空间用于各种用途。 其中之一是使用特性进行数据验证,另一个是字段、属性和方法的视觉描述,或者自定义特定属性的数据类型。 这三个类别在 .NET Framework 中被归类为验证特性、显示特性和数据建模特性。 本节使用验证特性来定义对象的验证规则
Using the Code
要使用 DataAnnotations
命名空间,您需要添加对程序集的引用——默认情况下,Visual Studio 项目模板中不包含此引用。 然后,您需要使用正确的特性来装饰您的对象。 例如,下面的代码使用一种不正确的方法,直接使用这些特性来装饰域实体。 接下来,我将重构此代码,使该实体不知道其验证。
public sealed class Customer
{
/// <summary>
/// Gets or sets the first name.
/// </summary>
/// <value>The first name.</value>
[Required(ErrorMessage = "The FirstName is a mandatory Field")]
[StringLength(10, ErrorMessage =
"The FirstName should be greater than 10 characters.")]
public string FirstName { get; set; }
/// <summary>
/// Gets or sets the last name.
/// </summary>
/// <value>The last name.</value>
[Required(ErrorMessage = "The LastName is a mandatory Field")]
[StringLength(10, ErrorMessage =
"The LastName should be greater than 10 characters.")]
public string LastName { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
[Required(ErrorMessage = "The Title is a mandatory Field")]
public string Title { get; set; }
}
可以使用通用验证器轻松验证Customer
实体,因为您知道我们只想验证那些具有DataAnnotations
特性的属性。
public sealed class GenericValidator<T>
{
/// <summary>
/// Validates the specified entity.
/// </summary>
/// <param name="entity">The entity.</param>
/// <returns></returns>
public IList<ValidationResult> Validate(T entity)
{
var results = new List<ValidationResult>();
var context = new ValidationContext(entity, null, null);
Validator.TryValidateObject(entity, context, results);
return results;
}
}
此时,我们可以很容易地针对Customer
实体测试验证器,如下所示
/// <summary>
/// Determines whether this instance [can validate customer].
/// </summary>
[TestMethod]
public void CanValidateCustomer()
{
Customer entity = new Customer { FirstName = "", LastName = "" };
GenericValidator<Customer> target = new GenericValidator<Customer>();
bool expected = false;
bool actual;
actual = target.Validate(entity).Count == 0;
Assert.AreEqual(expected, actual,
"The Entity should not be valid at this point.");
}
重构您的代码 – 好的方法
现在,要从域实体中删除验证,您需要创建一个代表域实体并包含验证规则的接口,然后从该接口继承域实体。 在此过程结束时,您应该能够编写如下代码
/// <summary>
/// Determines whether this instance [can validate customer].
/// </summary>
[TestMethod]
public void CanValidateCustomer()
{
Customer entity = new Customer { FirstName = "", LastName = "" };
GenericValidator<ICustomer> target = new GenericValidator<ICustomer>();
bool expected = false;
bool actual;
actual = target.Validate(entity).Count == 0;
Assert.AreEqual(expected, actual,
"The Entity should not be valid at this point.");
}
可用的验证框架
刚才介绍的验证技术只是 .NET 可用技术之一。 使用DataAnnotations
的优点在于它与 WPF 和 Silverlight 完美结合,并且它的设计方式适用于 MVVM 应用程序的所有层。 在ViewModel
部分,您将看到为什么DataAnnotations
方法是 WPF 或 Silverlight 的完美匹配。
微软创建的另一个有趣的框架是验证应用程序块,该框架随 Microsoft Enterprise Library 5.0 一起提供 (http://entlib.codeplex.com/)。 验证应用程序块使用相同的一般方法——根据使用特性(数据注释)或外部 XML 文件定义的一组规则来验证对象。 与DataAnnotations
的主要区别在于您用于验证对象的过程,但是您应该获得相同的最终结果。
另一个框架,是开源项目 NHibernate 的一部分,是 NHibernate 验证框架。 这可以在 http://sourceforge.net/projects/nhcontrib/ 作为 NHibernate Contrib 项目的一部分找到。 使用此框架的主要缺点是,除非您计划将 NHibernate 用作您的 O/RM,否则您将引入您各层中可能不需要的额外依赖项。 此框架还要求您使用与特定 O/RM 相关的验证规则来污染您的实体。
参考文献
- http://entlib.codeplex.com/
- http://sourceforge.net/projects/nhcontrib/
- EVIL (http://evil.codeplex.com) 一个开源项目,其工作方式与 VAB 库类似,使用装饰和规则集
- Active Record (http://www.castleproject.org/activerecord/index.html) 一个用于 NHibernate 的开源插件,可将您的域转换为 Active Record 域
- Conditions (http://conditions.codeplex.com) 另一个使用流畅界面而不是特性的开源框架
摘要
总而言之,重要的是保持域干净并且不知道您正在使用的验证规则或方法,但同样重要的是,您决定为编写的应用程序类型使用合适的框架。
历史
- 2011 年 4 月 22 日:初始版本
- 2011 年 5 月 18 日:更新的引用部分
- 2011 年 6 月 16 日:更新的代码