65.9K
CodeProject 正在变化。 阅读更多。
Home

在 .NET Framework 4 中的验证

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.27/5 (7投票s)

2011年4月23日

CPOL

3分钟阅读

viewsIcon

68062

downloadIcon

804

.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 相关的验证规则来污染您的实体。

参考文献

摘要

总而言之,重要的是保持域干净并且不知道您正在使用的验证规则或方法,但同样重要的是,您决定为编写的应用程序类型使用合适的框架。

历史

  • 2011 年 4 月 22 日:初始版本
  • 2011 年 5 月 18 日:更新的引用部分
  • 2011 年 6 月 16 日:更新的代码
© . All rights reserved.