很多时候在UI验证数据输入后就交给业务逻辑进行处理,在业务逻辑不会对数据进一步验证就进行操作。由于业务逻辑数据来源于UI,因此在UI验证数据就已经够安全;如果在业务逻辑再进行一次验证似乎有点多此一举。实际上我认为这样很不合理,因为业务逻辑本身就是一个独立体,把数据的合法性依赖于UI是很不应该的。但在业务逻辑中对成员的数据验证并不象UI那样有着方便的验证控件,如果手动对每个数据成员进行编码验证的确会增加很大的工作。为了解决这方面问题想出了通过Custom Attribute的方式来简化对象成员数据验证的功能;通过Attribute来配置需对象成员需要验证的方式,然后通过容器进行统一验证,从而达到简化验证代码的编写。
组件使用
通过以下方式可以描述一个类的成员验证描述:
[HFSoft.Validators.Certifier]
public class User
{
private string mUserCode;
[HFSoft.Validators.StringValidator("用户编号必须是5-12个字符",5,12)]
public string UserCode
{
get
{
return mUserCode;
}
set
{
mUserCode = value;
}
}
private DateTime mBrithday;
[HFSoft.Validators.DateValidator("出生日期必须在1900-1-1和2100-1-1之间","1900-1-1","2100-1-1")]
public DateTime Brithday
{
get
{
return mBrithday;
}
set
{
mBrithday = value;
}
}
private int mIndex;
[HFSoft.Validators.NumberValidator("请输入20-100之间的数值",20,100)]
public int Index
{
get
{
return mIndex;
}
set
{
mIndex = value;
}
}
}
当定义了验证的方式后就可以通过组件的容器对类的实例进行数据验证。
HFSoft.Validators.Container container = new HFSoft.Validators.Container();
container.Add(typeof(User));
User user = new User();
user.UserCode ="henryfan";
user.Brithday = DateTime.Parse("1979-1-28");
container.Valid(user);
把需要验证的类型添加到容器中,通过容器的Vialid方法对实例进行验证。
组件的实现
为了规定一个统一的验证规则,制定一个验证对象基础类:
[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
public class Validator:Attribute
{
public Validator()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
private Type mSource;
/// <summary>
/// 验证对象类型
/// </summary>
public Type Source
{
get
{
return mSource;
}set
{
mSource = value;
}
}
private System.Reflection.PropertyInfo mProperty;
/// <summary>
/// 相关验证的属性成员
/// </summary>
public System.Reflection.PropertyInfo Property
{
get
{
return mProperty;
}
set
{
mProperty = value;
}
}
public virtual void Valid(object source)
{
if(!OnValid(Property.GetValue(source,null)))
{
throw(new ValidatorException(Error));
}
}
protected virtual bool OnValid(object value)
{
return true;
}
private string mError="";
/// <summary>
/// 不符合验证抛出的异常信息
/// </summary>
public string Error
{
get
{
return mError;
}
set
{
mError = value;
}
}
}
通过Validator类派生出子类来实现不同的验证规则
StringValidator,DateValidator,NumberValidator,RegexValidator等。
[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property)]
public class StringValidator:Validator
{
public StringValidator(string error,int minlength,int maxlength)
{
//
// TODO: 在此处添加构造函数逻辑
//
Error = error;
MinLength= minlength;
MaxLength = maxlength;
}
private int mMinLength =1;
public int MinLength
{
get
{
return mMinLength;
}
set
{
mMinLength = value;
}
}
private int mMaxLength=0;
public int MaxLength
{