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

Microsoft Enterprise Library 5.0 - 验证块简介

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.62/5 (17投票s)

2011年9月18日

CPOL

6分钟阅读

viewsIcon

90128

downloadIcon

7807

通过示例介绍 Microsoft Enterprise Library 5.0 中验证块的常见任务

引言

Microsoft Enterprise Library 5.0 中的验证块用于定义验证规则,并在应用程序中以不同方式轻松管理它们。

它包含大量内置验证器,包括null验证、范围验证、自验证等。它还提供了一种出色的方式来根据预定义规则验证对象,并提供包含有价值信息的结果。

除了常见的验证机制,它还支持 WPF、WCF 和 ASP.NET 的特定技术验证。

在本文中,我将重点介绍验证块中的常见任务,并尝试通过示例进行解释。我开发了一个用于测试验证的演示应用程序,您可以在其中找到示例并了解其工作原理。这些示例取自演示项目,并使用 Microsoft Visual Studio 2010、.NET Framework 4.0 和 Microsoft Enterprise Library 5.0 开发。

您可以从以下地址获取 Microsoft Enterprise Library 程序集文件和其他相关资源

基础

验证块中有 3 种类型的验证器

  1. 值验证器
  2. 复合验证器
  3. 对象验证器

值验证器:执行特定验证,例如验证string的长度、检查值是否为null以及根据预定义范围验证数字。

复合验证器:允许与其他验证器结合使用以创建复杂的验证集。存在两种类型的复合验证:AND验证器和OR验证器。通过将这些复合验证器与其他验证器结合使用,可以定义验证器之间的验证逻辑。

对象验证器:执行为类型定义的所有验证,并支持对集合中的对象进行验证。

准备工作

要使用验证块,您必须引用所需的程序集。主要的验证块程序集是 Microsoft.Practices.EnterpriseLibrary.Validation.dll

如果您打算使用 ASP.NET、Windows Forms、WPF 或 WCF 的集成功能,您还必须引用以下列表中包含这些功能的相应程序集

  • 对于 ASP.NET,Microsoft.Practices.EnterpriseLibrary.Validation.Integration.AspNet.dll
  • 对于 Windows Forms,Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WinForms.dll
  • 对于 WPF,Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WPF.dll
  • 对于 WCF,Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF.dll

如何使用验证块

首先,您必须初始化一个验证器实例,您可以使用它通过以下几行代码创建和执行验证

ValidatorFactory valFactory = 
	EnterpriseLibraryContainer.Current.GetInstance<ValidatorFactory>();

在上面的代码中,Unity 依赖注入机制用于创建与验证相关的对象。但是,如果您愿意通过实现IServiceLocator接口,可以使用另一种依赖注入机制来实现不同的目的。

让我们创建要用于验证的客户

public class AttributeCustomer 
{
    [NotNullValidator(MessageTemplate = "Customer must have valid no")]
    [StringLengthValidator(5, RangeBoundaryType.Inclusive, 
		5, RangeBoundaryType.Inclusive, 
		MessageTemplate = "Customer no must have {3} characters.")]
    [RegexValidator("[A-Z]{2}[0-9]{3}", 
	MessageTemplate = "Customer no must be 2 capital letters and 3 numbers.")]
    public string CustomerNo { get; set; }
}

然后,我们根据我们的验证偏好创建一个所需的验证器。在此上下文中,我们更喜欢验证块属性方法。

Validator<AttributeCustomer> cusValidator = 
			valFactory.CreateValidator<AttributeCustomer>();

我们初始化需要验证的customer对象,并通过在customer对象类型中定义的属性进行验证。

var customer = new AttributeCustomer();
customer.CustomerNo = "AB123";
customer.FirstName = "Brown";
customer.LastName = "Green";
customer.BirthDate = "1980-01-01";
customer.CustomerType = "VIP";

ValidationResults valResults = cusValidator.Validate(customer);

最后,我们得到验证结果,我们可以检查对象是否有效。如果无效,我们可以找到验证失败的原因和失败来源(在此上下文中为对象属性)。

if (valResults.IsValid)
{
    MessageBox.Show("Customer information is valid");
}
else
{
    foreach (ValidationResult item in valResults)
    {
        // Put your validation detection logic
    }
}

方法

在验证过程中,您可以选择五种验证方法。每种方法都有其优缺点,但现在我不会关注这些细节。此外,可以同时应用多种方法。例如,您可以同时实现自验证和数据注释属性方法,这为您提供了更大的灵活性。

  1. 配置中的规则集
  2. 验证块属性
  3. 数据注释属性
  4. 自验证
  5. 以编程方式创建的验证器

配置中的规则集

在此方法中,我们将验证规则放入配置文件(ASP.NET 中的web.config和 Windows 应用程序中的app.config)。以下是显示如何定义验证规则的示例

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.
	Validation.Configuration.ValidationSettings, 
	Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, 
	Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
  </configSections>
  <validation>
    <type name="ELValidation.Entities.BasicCustomer" 
		defaultRuleset="BasicCustomerValidationRules"
      assemblyName="ELValidation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
      <ruleset name="BasicCustomerValidationRules">
        <properties>
          <property name="CustomerNo">
            <validator type="Microsoft.Practices.EnterpriseLibrary.
		Validation.Validators.NotNullValidator, 
		Microsoft.Practices.EnterpriseLibrary.Validation"
              negated="false" messageTemplate="Customer must have valid no"
              tag="CustomerNo" name="Not Null Validator" />
            <validator type="Microsoft.Practices.EnterpriseLibrary.
		Validation.Validators.StringLengthValidator, 
		Microsoft.Practices.EnterpriseLibrary.Validation"
              upperBound="5" lowerBound="5" lowerBoundType="Inclusive" 
		upperBoundType="Inclusive"
              negated="false" messageTemplate="Customer no must have {3} characters."
              tag="CustomerNo" name="String Length Validator" />
            <validator type="Microsoft.Practices.EnterpriseLibrary.
		Validation.Validators.RegexValidator, 
		Microsoft.Practices.EnterpriseLibrary.Validation"
              pattern="[A-Z]{2}[0-9]{3}" options="None" patternResourceName=""
              patternResourceType="" 
		messageTemplate="Customer no must be 2 capital letters and 3 numbers."
              messageTemplateResourceName="" messageTemplateResourceType=""
              tag="CustomerNo" name="Regex Validator" />
          </property>
        </properties>
      </ruleset>
    </type>
  </validation>
</configuration>

在我们的配置文件中,我们首先为 Enterprise Library 验证设置定义一个配置节。然后,我们按照示例所示定义我们的验证规则。首先,通过“type”标签定义要应用规则的类型,并定义该类型的每个属性以及该属性的相关验证。

我们可以手动编写验证规则,或者通过 Enterprise Library 配置工具来完成,该工具很可能位于以下路径

Program Files Folder\Microsoft Enterprise Library 5.0\Bin\EntLibConfig.NET4.exe

这个工具对您有很大帮助,并防止您在配置过程中遇到复杂性,因为手动操作可能很困难。

在此示例中,我们定义了一个规则集名称,BasicCustomerValidationRules,用于根据特定规则验证我们的对象,如以下几行所示

public class BasicCustomer : ICustomer
{
    public string CustomerNo { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string BirthDate { get; set; }
    public string CustomerType { get; set; }
}

Validator<BasicCustomer> cusValidator = 
	valFactory.CreateValidator<BasicCustomer>("BasicCustomerValidationRules");
ValidationResults valResults = cusValidator.Validate(customer);

我们测试customer对象,如果customerno的值不为null,它正好有 5 个字符,并且格式类似于 AB123。

验证块属性

在此方法中,我们通过 Enterprise Library 验证块中定义的属性来定义我们的验证。

[NotNullValidator(MessageTemplate = "Customer must have valid no")]
[StringLengthValidator(5, RangeBoundaryType.Inclusive, 
		5, RangeBoundaryType.Inclusive, 
		MessageTemplate = "Customer no must have {3} characters.")]
[RegexValidator("[A-Z]{2}[0-9]{3}", 
	MessageTemplate = "Customer no must be 2 capital letters and 3 numbers.")]
public string CustomerNo { get; set; }

在此示例中,我们检查customerno是否不为null,它正好有 5 个字符,并且格式类似于 AB123。

此外,消息模板是一种很好的方式,可以在失败时提供有意义的消息,并且可以灵活地被 Enterprise Library 验证块替换括号。

在此示例中,如果CustomerNo中的字符数与5不同,我们会收到错误消息,例如Customer no must have 5 characters

数据注释属性

在此方法中,我们通过System.ComponentModel.DataAnnotations程序集中定义的属性来定义我们的验证。

在下面的示例中,我们为CustomerNo属性定义了 3 条验证规则,以便它不能为null,它必须正好有 5 个字符,并且CustomerNo的格式应为AB123

[Required(ErrorMessage = "Customer no can not be empty")]
[StringLength(5, ErrorMessage = "Customer no must be 5 characters.")]
[RegularExpression("[A-Z]{2}[0-9]{3}", 
	ErrorMessage = "Customer no must be 2 capital letters and 3 numbers.")]
public string CustomerNo { get; set; }

此方法与 Entity Framework 和 ASP.NET 验证结合使用。

自验证

这种方法为我们创建和执行复杂的验证规则提供了很大的灵活性。

为了实现此方法,我们首先用对象类型修饰HasSelfValidation属性,如以下示例所示

[HasSelfValidation]
public class AttributeCustomer
{
    …
}

然后,我们通过在执行验证的方法顶部放置SelfValidation属性来编写我们的验证逻辑。

[SelfValidation]
public void Validate(ValidationResults validationResults)
{
    var age = DateTime.Now.Year - DateTime.Parse(BirthDate).Year;

    // Due to laws, only customers older than 18 can be registered 
    // to system and allowed to order products
    if (age < 18)
    {
        validationResults.AddResult(
            new ValidationResult("Customer must be older than 18",
                this,
                "BirthDate",
                null,
                null));
    }
}

在此示例中,我们检查BirthDate属性值,看客户是否大于 18 岁,然后在失败时将验证结果附加到验证结果集合中。

以编程方式创建的验证器

此方法与其他方法不同,因为验证规则是按编程方式创建的,并且独立于类型执行。

首先,我们定义我们的验证规则

Validator[] validators = new Validator[] 
{ 
    new NotNullValidator(false, "Value can not be NULL."),
    new StringLengthValidator(5, RangeBoundaryType.Inclusive, 
	5, RangeBoundaryType.Inclusive,  "Value must be between {3} and {5} chars.")
};

然后,根据您的偏好,将它们添加到一个复合验证器中。

var validator = new AndCompositeValidator(validators);

最后,我们针对要测试的对象执行验证规则并获取结果。

ValidationResults valResults = validator.Validate("Value to be tested…");

在此示例中,我们检查Value to be tested…是否不为null,并且它正好有五个字符。

最后,我想提一下针对集合的验证。实际上,它与对象的验证相似。

// Initialize our object and set the values
var customer = new AttributeCustomer();
            
FillCustomerInfo(customer);

// Create a list of objects and add the objects to be tested to the list
List<AttributeCustomer> customers = new List<AttributeCustomer>();
customers.Add(customer);

// Initialize our validator by providing the type of objects in the list and validate them
Validator cusValidator = new ObjectCollectionValidator(typeof(AttributeCustomer));
ValidationResults valResults = cusValidator.Validate(customers);

// Show our validation results
ShowResults(valResults);

结束语

验证块功能非常强大,确实节省了大量时间。此外,验证的实现和维护也很容易。当然,验证块比我在这篇文章中试图说明的范围要大,但我希望您能理解它的工作原理并开始在您的应用程序中使用它。最后,Microsoft Enterprise Library 5.0 具有针对 ASP.NET、Winforms、WPF 和 WCF 的集成功能。我将在我的下一篇文章中重点介绍这些集成功能。

历史

  • 2011 年 9 月 18 日:初始版本
© . All rights reserved.