注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 Cisco IOS下载
 帮助

Castle ActiveRecord学习实践(8):数据有效性的验证


2006-04-13 12:27:00
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://terrylee.blog.51cto.com/342737/67666
摘要:在我们录入数据时,对数据有效性的验证是必不可少的, ActiveRecord中如何去验证数据的有效性呢?本文将详细介绍这一内容。
 
主要内容
1.概述
2.使用Validation
3.如何扩展
4.深入分析验证

一.概述
在录入数据时,对数据有效性的验证是必不可少的,很多时候我们在UI层上就会做一层验证,但有时也需要在底层做一些必要的处理,这就要用到ActiveRecord中的数据有效性的验证。ActiveRecord为我们提供了如下几个验证:
n         ValidateEmail
n         ValidateIsUnique
n         ValidateRegExp
n         ValidateNotEmpty
n         ValidateConfirmation
 
二.如何使用
为了使用上面这些验证,我们必须用ActiveRecordValidationBase来代替ActiveRecordBase,即实体类必须继承于ActiveRecordValidationBase
[ActiveRecord("Customs")]

public class Custom : ActiveRecordValidationBase

{

    
//

}

ActiveRecordValidationBase类为我们提供了如下一个方法和属性:
方法|属性
说明
IsValid()
返回验证是否通过
ValidationErrorMessages
获取验证错误信息数组
下面看一个完整的例子代码,在这个程序中我们需要验证用户名不能为空,Email地址、邮政编码、电话号码的格式是否正确
[ActiveRecord("Customs")]

public class Custom : ActiveRecordValidationBase

{

    

    
private int _id;

    

    
private string _name;

    

    
private string _email;

    

    
private string _address;

    

    
private string _post;

    

    
private string _phone;

    

    [PrimaryKey(PrimaryKeyType.Native)]

    
public int ID

    
{

        
get return this._id; }

        
set this._id = value; }

    }


    

    [Property,ValidateNotEmpty]

    
public string Name

    
{

        
get return this._name; }

        
set this._name = value; }

    }


    

    [Property,ValidateEmail]

    
public string Email

    
{

        
get return this._email; }

        
set this._email = value; }

    }


    

    [Property]

    
public string Address

    
{

        
get return this._address; }

        
set this._address = value; }

    }


    

    [Property,ValidateRegExp(
@"\d{6}")]

    
public string Post

    
{

        
get return this._post; }

        
set this._post = value; }

    }


    

    [Property,ValidateRegExp(
@"(\(\d{3,4}\)|\d{3,4}-)?\d{8}")]

    
public string Phone

    
{

        
get return this._phone; }

        
set this._phone = value; }

    }


    

    
public static void DeleteAll()

    
{

        ActiveRecordBase.DeleteAll(
typeof(Custom));

    }


    

    
public static Custom[] FindAll()

    
{

        
return ((Custom[])(ActiveRecordBase.FindAll(typeof(Custom))));

    }


}

编写一些简单的测试代码,大家有兴趣可以看一下:
[Test]

public void TestNameValidation()

{   

    
//姓名为空

    Custom custom 
= new Custom();

    custom.Address 
= "TianJin";

    custom.Email 
= "lhj_cauc@hotmail.com";

    custom.Phone 
= "022-24096356";

    custom.Post 
= "300192";

    

    
//错误消息数

    
int expectedError = 1;

 

    Assert.IsFalse(custom.IsValid());

    Assert.AreEqual(expectedError,custom.ValidationErrorMessages.Length);

}


 

[Test]

public void TestPostValidation()

{

    
//邮政编码错误、Email错误

    Custom custom 
= new Custom();

    custom.Name 
= "Terry Lee";

    custom.Email 
= "lhj_cauc#hotmail.com";

    custom.Phone 
= "022-24096356";

    custom.Post 
= "222t";

    custom.Address 
= "Tianjin";

 

    
//错误消息数

    
int expectedError = 2;

    

    Assert.IsFalse(custom.IsValid());

    Assert.AreEqual(expectedError,custom.ValidationErrorMessages.Length);

}


 

[Test]

public void TestAllValidation()

{   

    
//全部正确

    Custom custom 
= new Custom();

    custom.Name 
= "Terry Lee";

    custom.Email 
= "lhj_cauc@hotmail.com";

    custom.Phone 
= "022-24096335";

    custom.Address 
= "TianJin";

    custom.Post 
= "300192";

 

    
//错误消息数

    
int expectedError = 0;

    

    Assert.IsTrue(custom.IsValid());

    Assert.AreEqual(expectedError,custom.ValidationErrorMessages.Length);

}
 
三.如何扩展
上面这些验证已经能够满足我们绝大多数的需求,但是我们也可以去添加自己的验证。来看看ActiveRecord中的Validation的类结构图(只画出了部分)
通过上图可以看到,如果想添加自己的验证,需要有一个继承AbstractValidator和继承于AbstractValidationAttribute的类就可以了,具体可以参考ActiveRecord的代码。
 
四.深入分析验证
通过上面的分析我们都知道所有的实体类都继承于ActiveRecordValidationBase基类,那么ActiveRecord是如何通过特性来进行验证的呢?下面我们结合源码进一步分析一下。
我们在属性上加上了验证, Attribute并不做任何实质性的工作,它只是调用验证器进行验证,先来看一下ValidateNotEmptyAttribute的代码:
[Serializable]

public class ValidateNotEmptyAttribute : AbstractValidationAttribute

{

    
public ValidateNotEmptyAttribute() : base(new NullCheckValidator())

    
{

    }


 

    
public ValidateNotEmptyAttribute(String errorMessage) : base(new NullCheckValidator(), errorMessage)

    
{

 

    }


}

所有验证工作都是在Validator中进行的,以NullCheckValidator为例来看它做了什么操作:
 
[Serializable]

public class NullCheckValidator : AbstractValidator

{

    
public NullCheckValidator()

    
{

 

    }


 

    
public override bool Perform(object instance, object fieldValue)

    
{

        
return fieldValue != null && fieldValue.ToString().Length != 0;

    }