一、简介及用途
在实际的项目开发中,我们总会需要对数据进行验证,以保证数据的可靠性,而为了使这些验证可以在不同的地方进行复用(如winform、web、WPF等),就需要将验证进行封装,EntLib的Validation模块就为我们解决了这个问题而产生的,其内置了多种常见的验证器,如字符串、日期、类型转换、正则表达式等,同时还提供了自定义验证的接口,方便我们根据实际的业务需求进行扩展。
同时,在Validation模块中还为我们加入了ASP.NET、WINFORM和WCF的验证器。
企业库提供了一个很强大的验证应用程序模块,特点是:
· 可以通过配置为你的程序中特定的类来定义规则集.
· 是为你的类的公有属性,即对外开放的属性进行验证的.
使用企业库验证应用程序模块的优势:
· 有助于保持一致的验证方法。
· 包括大多数标准验证,包括.NET数据类型校验.
· 它让您可以将多个规则集具有相同的类和该类的成员.
· 它可以让你申请一个或多个规则集时,您验证的对象.
企业库验证应用程序模块提供了下列几种验证方法:
· And CompositeValidator
· ContainsCharacters Validator
· Date Time RangeValidator
· Domain Validator
· Enum ConversionValidator
· Not Null Validator
· Object CollectionValidator
· Object Validator
· Or CompositeValidator
· PropertyComparison Validator
· Range Validator
· Regular ExpressionValidator
· Relative Date TimeValidator
· String LengthValidator
· Type ConversionValidator
· Single MemberValidators
企业库验证应用程序模块有2种使用模式:
二、使用方法
企业库的Validation模块为我们提供了2种验证方式:
1、在具体的类、属性、字段和方法前添加特性,如:[StringLengthValidator(1, 25)]
2、使用企业库提供的配置工具,通过配置的方式将验证信息存入配置文件
本文讲的是代码模式,
下面介绍如何使用Microsoft Enterprise Library 5.0中的验证应用程序模块的代码模式.
1. 要使用缓存应用程序模块, 需要导入相应的Dll文件,在此我们要导入的是Microsoft.Practices.EnterpriseLibrary. Validation.dll ,System.ComponentModel.DataAnnotations.dll ,并添加需要的引用:
添加引用:
usingMicrosoft.Practices.EnterpriseLibrary.Validation.Validators;
usingMicrosoft.Practices.EnterpriseLibrary.Validation;
usingSystem.Collections.Generic;
2. 测试:
using System;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;
using System.Collections.Generic;
namespace test
{
class Program
{
static int index = 1;
static void Main(string[] args)
{
//验证Customer类
Validator<Customer> customerValidator = ValidationFactory.CreateValidator<Customer>();
//设置Customer的CustomerName字段为null
Customer myCustomer = new Customer(null);
ValidationResults vr = customerValidator.Validate(myCustomer);
Scan(vr);
//设置Customer的CustomerName
myCustomer.CustomerName = "HuangCong";
vr = customerValidator.Validate(myCustomer);
Scan(vr);
//创建一个日期
DateTime dt = new DateTime(1988, 01, 01);
//创建一个日期验证器
Validator<DateTime> v1 = new DateTimeRangeValidator(DateTime.Parse("2009-01-01"), DateTime.Parse("2010-01-01"));
vr = v1.Validate(dt);
Scan(vr);
dt = new DateTime(2009, 5, 5);
vr = v1.Validate(dt);
Scan(vr);
/*
其他的验证类还有如下这些,大家可以自己实验:
And Composite Validator
Contains Characters Validator
Date Time Range Validator
Domain Validator
Enum Conversion Validator
Not Null Validator
Object Collection Validator
Object Validator
Or Composite Validator
Property Comparison Validator
Range Validator
Regular Expression Validator
Relative Date Time Validator
String Length Validator
Type Conversion Validator
Single Member Validators
参考网站:http://msdn.microsoft.com/en-us/library/ff664694%28v=PandP.50%29.aspx
*/
}
public class Customer
{
//Not Null Validator 验证器,验证该属性不能为空值
[NotNullValidator]
public string CustomerName;
public Customer(string customerName)
{
this.CustomerName = customerName;
}
}
private static void Scan(ValidationResults vr)
{
Console.WriteLine("测试{0}:", index++);
if (!vr.IsValid)
{
Console.WriteLine("出错");
}
else
{
Console.WriteLine("正确");
}
Console.WriteLine("---------------------------------------");
}
}
}
3. 运行结果:
System.ComponentModel.DataAnnotations下的ValidationAttribute类(MSDN描述:作为所有验证特性的基类),所以我们如果需要使用特性的方式为实体类或字段等进行验证时必须为项目添加System.ComponentModel.DataAnnotations引用。
接着我们来看下,如何使用特性进行验证:
在代码中引入:
1
using Microsoft.Practices.EnterpriseLibrary.Validation;
2
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
然后就可以在类、属性、字段和方法前添加特性了,下面是一个简单的字符串长度验证,表示输入的用户名长度必须在1-16之间:
1 [StringLengthValidator(1, 16, MessageTemplate = "用户名长度必须在1-16位之间")]
2 [StringLengthValidator(1,16,MessageTemplateResourceType=typeof(EntlibStudy.Model.Properties.Resources), MessageTemplateResourceName = "SIDMessage")]
3 public string Sid { get; set; }
这边有2点需要注意:
1、我书写了2种验证失败的错误消息,一种是直接书写MessageTemplate,这种方式的好处就是简便(在使用企业库配置工具进行配置时也是设置这个属性),另一种是将错误消息统一放在一个资源文件中,这种的好处是可以将所有的错误消息统一管理,而且如果项目需要进行国际化处理时,可以直接添加新的资源文件即可,坏处是书写起来比较烦,需要指定资源文件的类型及对应消息的资源名。
具体关于StringLengthValidator的使用在下面会讲到。
2、使用特性进行验证时,特性只能应用于public的字段或属性,否则会报错。在3.0以前没有自动属性时我们通常会使用一下方式书写属性:
1 [StringLengthValidator(1, 16, MessageTemplate = "用户名长度必须在1-16位之间")]
2 private string _aid;
3 public string Aid
{
get { return _aid; }
set { _aid = value; }
}
很不幸的是,这种方式是错的,因为特性指定的字段是private的,而且就算把特性书写到属性Aid上也是不可行的,因为最终还是为_aid赋值。
Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
企业库验证应用程序模块之配置文件模式:
三、Validation模块内置的多种验证器的介绍
在Validation模块中已经内置了很多验证器,这些验证器也有所不同,我自己总结了一下这些验证的分类:
1、可作为特性的验证器,这种验证器是可以直接通过特性为类、属性、字段段进行验证,同时又可以通过配置进行验证。主要有:
ContainsCharactersValidatorAttribute——是否包含字符串验证
DateTimeRangeValidatorAttribute——时间范围验证
DomainValidatorAttribute——通过检查验证对象,判断它是否属于一个集合
EnumConversionValidatorAttribute——检查字符串是否可以转换成枚举中的某一项
HasSelfValidationAttribute——自我验证,只能用于类,为SelfValidationAttribute服务
IgnoreNullsAttribute——可为空验证
NotNullValidatorAttribute——不为空验证
ObjectCollectionValidatorAttribute——对象集合类型验证
ObjectValidatorAttribute——对象类型验证
PropertyComparisonValidatorAttribute——属性比较验证
RangeValidatorAttribute——范围验证,判断对象是否在一个指定范围内
RegexValidatorAttribute——正则表达式验证
RelativeDateTimeValidatorAttribute——检查日期是否属于一个范围相对于当前时间或日期
SelfValidationAttribute——对调用一个方法进行自验证
StringLengthValidatorAttribute——字符串长度验证
TypeConversionValidatorAttribute——类型转换验证,判断是否可以转换成指定类型
ValidatorComposition——验证组合器,可以将不同的验证组合在一起
2、独立验证器,主要是为第一种验证服务,可以进行多种验证组合在一起进行复杂验证,如:
AndCompositeValidator——组合验证,逻辑与验证,所包含的多种验证全部通过则通过
OrCompositeValidator——组合验证,逻辑或验证,所包含的多种验证有一个通过则通过
3、自定义验证,这种则是为需要根据自己的业务逻辑进行扩展验证所提供的一个扩展。
首先来介绍下第一种验证,可作为特性的验证器:
这类验证工作原理简单的说就是通过特性类来接收要验证的信息,再通过特性类的DoCreateValidator来创建相应的验证类来进行验证。
*具体验证器特性类
*这类验证器的特性最终都是继承自抽象类:BaseValidationAttribute,在这个类的主要作用就是为子类提供错误消息和规则的抽象封装
1
public abstract class BaseValidationAttribute : ValidationAttribute
主要有以下几个字段及方法:
1、ruleset:规则集,开发人员可以为要验证的对象设置规则集,可以在每个规则集下建立针对某个字段或属性等的不同验证方式,例如在A规则集中,对Name字段需要有长度1-16的限制,而在B规则集中则是是否包含“test”字符串,这样通过制定不同的规则集则可以根据实际需求进行不同的验证。
2、messageTemplate,消息模板,指定验证不通过的错误消息
3、messageTemplateResourceType,消息模板所在资源类型,指定消息所存放的资源的类型
4、messageTemplateResourceName,消息模板所在资源名称,指定消息所存放的资源名称
5、tag,验证标签,获取或设置标签所代表的特征验证的结果记录
6、string GetMessageTemplate(),获取消息模板的方法,通过指定的messageTemplateResourceType和messageTemplateResourceName获取错误消息
7、bool IsValid(),重写ValidationAttribute.IsValid方法
在具体的验证特性类和BaseValidationAttribute之间还存在着2个特性类:
1
public abstract class ValidatorAttribute : BaseValidationAttribute, IValidatorDescriptor
*这个类的作用是抽象出验证逻辑以供子类使用:
1、方法CreateValidator,调用DoCreateValidator创建的Validator实例,并将tag和消息模板赋给Validator实例。
2、方法DoCreateValidator,用以创建实现Validator类的特定验证实例,以供各验证器进行验证。
1
public abstract class ValueValidatorAttribute : ValidatorAttribute
*这个类的作用是为各验证器的特性类提供抽象,同时重写了父类方法:
1、方法IsValid,重写了BaseValidationAttribute.IsValid,用以判断对象值是否有效。
2、方法FormatErrorMessage,重写了ValidationAttribute,格式化错误消息
3、属性Negated,用以获取或设置否定逻辑
这样我们就可以清楚的知道每个验证器特性类的具体继承关系了:
BaseValidationAttribute->ValidatorAttribute ->ValueValidatorAttribute ->具体验证器特性类,看图可以更加直观一点(为了看的清楚,我这边仅放了2个具体的验证器特性类):
至于具体的验证器特性类则根据不同业务逻辑进行设置,这边就不讲解,想了解的朋友可以或直接看源代码。
*具体验证类
在上面已经说过,具体的验证器验证是通过验证器的特性类(如:StringLengthValidatorAttribute)调用ValidatorAttribute类中的DoCreateValidator方法来创建具体验证器(如:StringLengthValidator)来进行验证。
而具体的验证(如:StringLengthValidator)具体结构也是和其特性类一样,通过一层层的实现来完成最终的验证的,首先来看下具体的继承层次:
Validator->Validator<T>->ValueValidator<T>->具体的验证器,具体见图:
1
public abstract class Validator
*抽象类Validator是所有验证器的顶级父类,其中定义了:
1、属性MessageTemplate,用以存放验证消息
2、属性Tag,用以存放验证结果
3、抽象属性DefaultMessageTemplate,当MessageTemplate为空时,验证器从DefaultMessageTemplate中获取验证消息
4、抽象方法DoValidate,抽象定义了验证方法
5、方法Validate,调用抽象方法DoValidate
6、方法LogValidationResult,记录验证结果
7、方法GetMessage,通过验证的对象及对象的值获取验证消息
1. 新建一个控制台应用程序,并创建一个Customer类,其代码如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{}
public class Customer
{
public string CustomerName;
public Customer(string customerName)
{
this.CustomerName = customerName;
}
public int Test()
{
return -5;
}
}
}
2. 运行EntLibConfig.exe, 选择Blocks菜单 ,单击 Add Validation Settings .
3. 点击Validated Types 区块右上角的加号按钮,然后点击 Add Type to Validate,这时会要你选择要验证的类,因为我们是想对Customer类的属性进行验证,所以我们要导入我们刚刚创建的类,点击并Add from File找到我们的应用程序Debug文件夹下的ConsoleApplication1.exe(根据你创建时起的名字而不同),Customer类就包含在这个程序内:
4. 导入后,我们就可以看到多了个ConsoleApplication1程序集,接着我们要选择它所包含的Customer类,如下图所示,选择后点击OK:
5. 在Customer面板上右键— Add Validation Ruleset:
6. 在设置Customer面板中的Defaule Ruleset属性为新创建的Validation Ruleset,接着在Validation Ruleset面板右键—Select Members,在弹出的选择框中选择
7. 在弹出的成员选择界面,我们选择要测试的Test方法和CustomerName属性:
8. 在Field:CustomerName面板上右键—Add Validators –Add Not Null Validator:
9. 对该验证器的设置如下图所示:
10. 在Method:Test面板上右键—Add Validators –Add Range Validator:
11. 对该验证器的设置如下图所示:
12. 点击 File 菜单,单击 Save,保存为一个App.config文件,可以先保存到桌面,之后要用到它.
13. 将App.config添加到工程中,并添加需要的引用,如图所示:
14. 测试:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Validator<Customer> customerValidator = ValidationFactory.CreateValidator<Customer>("Validation Ruleset");
Customer myCustomer = new Customer(null);
ValidationResults r = customerValidator.Validate(myCustomer);
if (!r.IsValid)
{
for (int i = 0; i < r.Count; i++)
{
Console.WriteLine("出错{0}:" + r.ElementAt(i).Message, i + 1);
}
}
else
{
Console.WriteLine("正确");
}
}
}
public class Customer
{
public string CustomerName;
public Customer(string customerName)
{
this.CustomerName = customerName;
}
public int Test()
{
return -5;
}
}
}
15. 运行结果: