本文是为后面的学习之路做铺垫,简单介绍下企业库中的Validation模块的一些相关知识,包括Validation模块的简介、用途、使用方法、默认提供的多种验证器的介绍等。
一、简介及用途
在实际的项目开发中,我们总会需要对数据进行验证,以保证数据的可靠性,而为了使这些验证可以在不同的地方进行复用(如winform、web、WPF等),就需要将验证进行封装,EntLib的Validation模块就为我们解决了这个问题而产生的,其内置了多种常见的验证器,如字符串、日期、类型转换、正则表达式等,同时还提供了自定义验证的接口,方便我们根据实际的业务需求进行扩展。
同时,在Validation模块中还为我们加入了ASPNET、WINFORM和WCF的验证器。
二、使用方法
企业库的Validation模块为我们提供了2种验证方式:
1、在具体的类、属性、字段和方法前添加特性,如:[StringLengthValidator(1, 25)]
2、使用企业库提供的配置工具,通过配置的方式将验证信息存入配置文件
当然你也可以动态的添加验证规则,这个就不是常规使用方式了,这里就不讨论了。
首先介绍下第一种验证方式:
在最新的EntLib5中,Validation模块被进行了修改,各验证Attribute的继承也进行了修改,导致了原有的4.1直接在字段等前面书写Attribute无法使用。
会显示错误信息:StringLengthValidator不是一个有效的AttributeClass
在上面链接的文章里已经需要引用System.ComponentModel.DataAnnotations命名空间,主要原因就是Validation模块的所有验证器都是继承自命名空间System.ComponentModel.DataAnnotations下的ValidationAttribute类(MSDN描述:作为所有验证特性的基类),所以我们如果需要使用特性的方式为实体类或字段等进行验证时必须为项目添加System.ComponentModel.DataAnnotations引用。
接着我们来看下,如何使用特性进行验证:
在代码中引入:
1 2 |
using Microsoft.Practices.EnterpriseLibrary.Validation; using Microsoft.Practices.EnterpriseLibrary.Validation.Validators; |
然后就可以在类、属性、字段和方法前添加特性了,下面是一个简单的字符串长度验证,表示输入的用户名长度必须在1-16之间:
1 2 3 4 5 |
[StringLengthValidator(1, 16, MessageTemplate = "用户名长度必须在1-16位之间")] [StringLengthValidator(1, 16, MessageTemplateResourceType = typeof(EntlibStudy.Model.Properties.Resources), MessageTemplateResourceName = "SIDMessage")] public string Sid { get; set; } |
这边有2点需要注意:
1、我书写了2种验证失败的错误消息,一种是直接书写MessageTemplate,这种方式的好处就是简便(在使用企业库配置工具进行配置时也是设置这个属性),另一种是将错误消息统一放在一个资源文件中,这种的好处是可以将所有的错误消息统一管理,而且如果项目需要进行国际化处理时,可以直接添加新的资源文件即可,坏处是书写起来比较烦,需要指定资源文件的类型及对应消息的资源名。
具体关于StringLengthValidator的使用在下面会讲到。
2、使用特性进行验证时,特性只能应用于public的字段或属性,否则会报错。在3.0以前没有自动属性时我们通常会使用一下方式书写属性:
1234567 [StringLengthValidator(1, 16, MessageTemplate = "用户名长度必须在1-16位之间")]private string _aid;public string Aid{get { return _aid; }set { _aid = value; }}很不幸的是,这种方式是错的,因为特性指定的字段是private的,而且就算把特性书写到属性Aid上也是不可行的,因为最终还是为_aid赋值。
接下来应该是介绍如何使用企业库的配置工具进行配置了,不过有关配置的方法园子里已经有很多人写过了,想学习的朋友可以到这边查看:
Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
Enterprise Library 4.1 Validation Block 快速使用图文笔记
这2篇都已经将每步的配置进行截图,已经很详细了,我就不多介绍了。
三、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 |
public abstract class Validator<T> : Validator |
*抽象类Validator<T>继承自抽象类Validator,主要功能是为抽象类Validator扩展泛型验证。
1 |
public abstract class ValueValidator<T> : Validator<T> |
*抽象类ValueValidator<T>继承自抽象类Validator<T>,其中定义了:
1、属性Negated,用以获取或设置否定逻辑
2、方法DefaultNonNegatedMessageTemplate,获取默认非否定验证消息模板
3、方法DefaultNegatedMessageTemplate,获取默认否定验证消息模板
4、重写属性DefaultMessageTemplate,同时定义了sealed,子类将无法继承,重写的内容为,根据属性Negated调用方法DefaultNonNegatedMessageTemplate或方法DefaultNegatedMessageTemplate
*具体的验证类继承了抽象类ValueValidator<T>通过重写Validator.DoValidate并根据自身业务逻辑进行验证,同时实现了抽象类ValueValidator<T>定义的方法DefaultNonNegatedMessageTemplate和DefaultNegatedMessageTemplate
至此我就企业库的Validation模块的基本信息、使用方法及验证器的基本实现层次进行了介绍,由于本文已经比较长了,所以后续的各种验证器的使用将放到下一篇进行介绍。
PS:本文的内容都是我个人的理解,同时参考了企业库Validation模块源代码,可能写的比较凌乱,而且在一些功能用途上存在偏差,如有朋友发现问题敬请指正,谢谢了!mOm