Castle ActiveRecord学习实践(8):数据有效性的验证
2006-04-13 12:27:00
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://terrylee.blog.51cto.com/342737/67666 | ||||||
摘要:在我们录入数据时,对数据有效性的验证是必不可少的, ActiveRecord中如何去验证数据的有效性呢?本文将详细介绍这一内容。
主要内容
1.概述
2.使用Validation
3.如何扩展
一.概述
在录入数据时,对数据有效性的验证是必不可少的,很多时候我们在UI层上就会做一层验证,但有时也需要在底层做一些必要的处理,这就要用到ActiveRecord中的数据有效性的验证。ActiveRecord为我们提供了如下几个验证:
n ValidateEmail
n ValidateIsUnique
n ValidateRegExp
n ValidateNotEmpty
n ValidateConfirmation
二.如何使用
为了使用上面这些验证,我们必须用ActiveRecordValidationBase来代替ActiveRecordBase,即实体类必须继承于ActiveRecordValidationBase。
[ActiveRecord("Customs")]![]() public class Custom : ActiveRecordValidationBase![]() {![]() //![]() }ActiveRecordValidationBase类为我们提供了如下一个方法和属性:
下面看一个完整的例子代码,在这个程序中我们需要验证用户名不能为空,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;![]() } |








}
}
通过上图可以看到,如果想添加自己的验证,需要有一个继承