Castle ActiveRecord学习(六)数据验证
参考、来源:http://www.cnblogs.com/Terrylee/archive/2006/04/13/374173.html
https://github.com/castleproject/ActiveRecord/blob/master/docs/validation-support.md
主要内容
1.概述
2.使用Validation
3.如何扩展
4.深入分析验证
一.概述
在录入数据时,对数据有效性的验证是必不可少的,很多时候我们在UI层上就会做一层验证,但有时也需要在底层做一些必要的处理,这就要用到ActiveRecord中的数据有效性的验证。ActiveRecord为我们提供了如下几个验证:
1.ValidateEmail
2.ValidateIsUnique
3.ValidateRegExp
4.ValidateNonEmpty
5.ValidateConfirmation
需要引入:using Castle.Components.Validator;
二.如何使用
为了使用上面这些验证,我们必须用ActiveRecordValidationBase来代替ActiveRecordBase,即实体类必须继承于ActiveRecordValidationBase。
[ActiveRecord("Customs")]
public class Custom : ActiveRecordValidationBase{ }
ActiveRecordValidationBase类为我们提供了如下一个方法和属性:
IsValid():返回验证是否通过
ValidationErrorMessages:获取验证错误信息数组
[ActiveRecord("Customs")]
public class Custom : ActiveRecordValidationBase
{
//IsValid():返回验证是否通过
//ValidationErrorMessages:获取验证错误信息数组
private int _id;
private string _name;
private string _email;
private string _address;
private string _post;
private string _phone; [PrimaryKey(PrimaryKeyType.Identity)]
public int ID
{
get { return this._id; }
set { this._id = value; }
} [Property, ValidateNonEmpty]
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))));
}
}
三.如何扩展
上面这些验证已经能够满足我们绝大多数的需求,但是我们也可以去添加自己的验证。来看看ActiveRecord中的Validation的类结构图(只画出了部分)
需要继承AbstractValidator和继承于AbstractValidationAttribute的类
四.深入分析验证
通过上面的分析我们都知道所有的实体类都继承于ActiveRecordValidationBase基类,那么ActiveRecord是如何通过特性来进行验证的呢?下面我们结合源码进一步分析一下。
我们在属性上加上了验证, Attribute并不做任何实质性的工作,它只是调用验证器进行验证,示例代码:
Model中使用:
using Castle.ActiveRecord;
using Castle.ActiveRecord.Queries;
using NHibernate;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Models
{
[ActiveRecord("UserInfo")]
public class UserInfo : ActiveRecordValidationBase<UserInfo>//必须继承ActiveRecordValidationBase
{
[Validators.ValidateIsUnique ,Property("Name")]//加入验证特性描述
public virtual string Name { get; set; }
}
}
using System;
using System.Collections;
using Castle.ActiveRecord.Framework.Internal;
using NHibernate;
using NHibernate.Classic;
using NHibernate.Criterion;
using Castle.Components.Validator;//需要添加引用
using Castle.ActiveRecord; namespace Models.Validators
{
[Serializable]
public class IsUniqueValidator : AbstractValidator
{
/// <summary>
/// Initializes a new instance of the <see cref="IsUniqueValidator"/> class.
/// </summary>
public IsUniqueValidator()
{
} /// <summary>
/// Perform the check that the property value is unqiue in the table
/// </summary>
/// <param name="instance"></param>
/// <param name="fieldValue"></param>
/// <returns><c>true</c> if the field is OK</returns>
public override bool IsValid(object instance, object fieldValue)
{
Type instanceType = instance.GetType();//需要验证的属性 所在类
string name = fieldValue.ToString();//属性值
//验证逻辑
if (name == "jay")
{
return true;
}
return false; //ActiveRecordModel model = ActiveRecordBase.GetModel(instance.GetType()); //while (model != null)
//{
// if (model.PrimaryKey != null)
// {
// pkModel = model.PrimaryKey;
// } // model = model.Parent;
//} //if (pkModel == null)
//{
// throw new ValidationFailure("We couldn't find the primary key for " + instanceType.FullName + " so we can't ensure the uniqueness of any field. Validatior failed");
//} //IsUniqueValidator.fieldValue = fieldValue; //SessionScope scope = null;
//FlushMode? originalMode = null;
//if (SessionScope.Current == null /*||
// SessionScope.Current.ScopeType != SessionScopeType.Transactional*/)
//{
// scope = new SessionScope();
//}
//else
//{
// originalMode = ActiveRecordBase.holder.CreateSession(instanceType).FlushMode;
// ActiveRecordBase.holder.CreateSession(instanceType).FlushMode = FlushMode.Never;
//} //try
//{
//return (bool)ActiveRecordMediator.Execute(instanceType, CheckUniqueness, instance);
//}
//finally
//{
// if (scope != null)
// {
// scope.Dispose();
// } // if (originalMode != null)
// {
// ActiveRecordBase.holder.CreateSession(instanceType).FlushMode = originalMode ?? FlushMode.Commit;
// }
//}
} //private object CheckUniqueness(ISession session, object instance)
//{
// ICriteria criteria = session.CreateCriteria(instance.GetType()); // if (Property.Name.Equals(pkModel.Property.Name, StringComparison.InvariantCultureIgnoreCase))
// {
// // IsUniqueValidator is on the PrimaryKey Property, simplify query
// criteria.Add(Expression.Eq(Property.Name, fieldValue));
// }
// else
// {
// object id = pkModel.Property.GetValue(instance, new object[0]);
// ICriterion pKeyCriteria = (id == null)
// ? Expression.IsNull(pkModel.Property.Name)
// : Expression.Eq(pkModel.Property.Name, id);
// criteria.Add(Expression.And(Expression.Eq(Property.Name, fieldValue), Expression.Not(pKeyCriteria)));
// }
// return criteria.List().Count == 0;
//} /// <summary>
/// Builds the error message when the property value is not unique 构造错误消息
/// </summary>
/// <returns></returns>
protected override string BuildErrorMessage()
{
if (!String.IsNullOrEmpty(ErrorMessage))
return ErrorMessage;
return String.Format("{0} is currently in use. Please pick up a new {0}.", Property.Name);
} /// <summary>
/// Gets a value indicating whether this validator supports browser validation. 是否支持客户端验证
/// </summary>
/// <value>
/// <see langword="true"/> if browser validation is supported; otherwise, <see langword="false"/>.
/// </value>
public override bool SupportsBrowserValidation
{
get { return false; }
} /// <summary>
/// Applies the browser validation by setting up one or
/// more input rules on <see cref="IBrowserValidationGenerator"/>.
/// </summary>
/// <param name="config">The config.</param>
/// <param name="inputType">Type of the input.</param>
/// <param name="generator">The generator.</param>
/// <param name="attributes">The attributes.</param>
/// <param name="target">The target.</param>
public override void ApplyBrowserValidation(BrowserValidationConfiguration config, InputElementType inputType,
IBrowserValidationGenerator generator, IDictionary attributes, string target)
{
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Castle.ActiveRecord.Framework.Validators;
using Castle.Components.Validator; namespace Models.Validators
{
/// <summary>
/// Validate that the property's value is unique in the database when saved
/// </summary>
[Serializable]
public class ValidateIsUniqueAttribute : AbstractValidationAttribute
{
private readonly IValidator validator; /// <summary>
/// Initializes a new instance of the <see cref="ValidateIsUniqueAttribute"/> class.
/// </summary>
public ValidateIsUniqueAttribute()
{
validator = new IsUniqueValidator();
} /// <summary>
/// Initializes a new instance of the <see cref="ValidateIsUniqueAttribute"/> class.
/// </summary>
/// <param name="errorMessage">The error message.</param>
public ValidateIsUniqueAttribute(String errorMessage)
: base(errorMessage)
{
validator = new IsUniqueValidator();
} /// <summary>
/// Constructs and configures an <see cref="IValidator"/>
/// instance based on the properties set on the attribute instance.
/// </summary>
/// <returns></returns>
public override IValidator Build()
{
ConfigureValidatorMessage(validator);
return validator;
}
}
}
前台使用:
protected void Button6_Click(object sender, EventArgs e)
{
Models.UserInfo tui = new Models.UserInfo();
tui.Name = TextBox2.Text;
if (tui.IsValid())
{
ltlMsg.Text = "验证通过";
}
else
{
ltlMsg.Text = "验证失败";
}
}
五、启动程序时,可以初始化数据、根据模型生成数据表、运行指定的Sql文件创建数据库:
protected void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
//AuthConfig.RegisterOpenAuth();
//RouteConfig.RegisterRoutes(RouteTable.Routes);
InitActiveRecord();
} //Castle Record Register Model
private void InitActiveRecord()
{
try
{
//加载配置文件
string NHibernateFilePath = Server.MapPath("~/NHibernate.config");
XmlConfigurationSource source = new XmlConfigurationSource(NHibernateFilePath);
//注册数据模型
ActiveRecordStarter.Initialize(source, typeof(Models.LogInfo), typeof(Models.UserInfo), typeof(Models.ThemeInfo), typeof(Models.CommentInfo), typeof(Models.CategoryInfo));
//根据模型生成数据库
//ActiveRecordStarter.CreateSchema();
//运行指定的数据库脚本生成数据库等
//ActiveRecordStarter.CreateSchemaFromFile("MySqlScript.sql");
}
catch (Exception)
{
throw;
}
}
六.使用空属类型
在进行数据库操作时,有时候需要进行空值的处理,在ActiveRecord中给我们提供了一组空属类型,可以方便的进行处理,比如可以这样写属性:
[Property("CreateDate")]
public virtual Nullable<DateTime> CreateDate { get; set; }
七.使用枚举类型
定义:
public enum StatusType
{
Editing = 0,
Published = 1,
Archived = 2
}
[Property("status_id")]
public virtual StatusType Status { get; set; } 使用:
Models.UserInfo userinfo = new Models.UserInfo();
userinfo.Status = Models.UserInfo.StatusType.Archived;
八.Hooks
有时候我们会在保存,加载,删除等操作时做一些必需的处理,这时可以通过重载以下三个方法来实现:
BeforeSave(IDictionary state)
BeforeLoad(IDictionary state)
BeforeDelete(IDictionary state)
比如说我们想在保存的时候设置创建时间为当前时间,可以这样去写:
protected override bool BeforeSave(IDictionary state)
{
state["Created"] = DateTime.Now;
return true;
}
Castle ActiveRecord学习(六)数据验证的更多相关文章
- Castle ActiveRecord学习实践
Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务. ...
- Castle ActiveRecord学习(三)数据映射及特性描述
Model中的Demo: using Castle.ActiveRecord; using Castle.ActiveRecord.Queries; using System; using Syste ...
- Castle ActiveRecord学习(一)简介
简介 来源:http://www.cnblogs.com/zxj159/p/4082987.html 一.Active Record(活动记录)模式 Active Record是业务逻辑层中(< ...
- Castle ActiveRecord学习(五)使用HQL语句查询
来源:http://www.cnblogs.com/Terrylee/archive/2006/04/12/372823.html 一.HQL简单介绍HQL全名是Hibernate Query Lan ...
- Castle ActiveRecord学习(二)配置、引用、程序启动
来源:http://www.cnblogs.com/zxj159/p/4082987.html 配置数据库驱动: Model层引用:Castle.ActiveRecord.dll.NHibernate ...
- JFinal Web开发学习(六)验证码验证和注册细节
效果: 实现了注册界面的验证码验证.确认密码.密码md5加盐加密.C3P0插件数据库操作.读取外部配置文件. 1.在注册页面添加了确认密码输入框,修改了字段名称 <!DOCTYPE html&g ...
- Castle ActiveRecord学习(四)延迟加载、分页查询、where条件
一.延迟加载 //用户发布的主题,一对多:Table:外键表:ColumnKey:外键:Lazy:延迟加载:Cascade:级联操作(级联删除) [HasMany(typeof(ThemeInfo), ...
- Castle ActiveRecord学习(八)事务
代码: public void UpdateThemeInfo(int id) { //事务 using (TransactionScope ctran = new TransactionScope( ...
- Castle ActiveRecord学习(七)使用日志
暂无 参考:http://terrylee.cnblogs.com/archive/2006/04/14/374829.html
随机推荐
- 20155315 2016-2017-2 《Java程序设计》第八周学习总结
教材学习内容总结 第14章 NIO与NIO2 1.认识NIO NIO使用频道(Channel)来衔接数据节点,在处理数据时,NIO可以让你设定缓冲区(Buffer)容量,在缓冲区中对感兴趣的数据区块进 ...
- java 8 新特性之Stream的排序/分类
Stream简介 Stream是Java8提供的一个新的API,它位于java.util.stream包下.Stream API提供了一种新的方式来对Java集合进行操作,这种操作方式极大的提高了Ja ...
- 浅谈 Gevent 与 Tornado(转)
原文:http://www.pywave.com/2012/08/17/about-gevent-and-tornado/ 还是前几月的时候,几乎在同一时间,自己接触到了 Gevent 和 Torna ...
- 7z 7zip 日期、时间,文件名
from: http://hi.baidu.com/guicomeon/item/c0957c373972fbc52f8ec26e 先说明一点,要注意区分当前所使用的系统,中文系统和英文系统是有区别的 ...
- OpenSSL生成root CA及签发证书
一.openssl 简介 openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用.健壮.功能完备的工具套件,用以支持SSL/TLS 协议的实现.官网:https://www.openss ...
- 使用anaconda安装tensorflow (windows10环境)
版权声明:勤学 修德 明辨 笃实 - CSDN周雄伟 https://blog.csdn.net/ebzxw/article/details/80701613 已有环境:python3.7.1 ana ...
- Django 组件content_type
content type: django内置组件,这个组件帮忙做连表操作(混搭连表) 适用场景:适用于一张表与多张表同时做关联的时候.直接导入就可以使用了. 关联数据库所有的表:可以快速插入数据,并且 ...
- 在eclipse中使用mybatis-generator自动创建代码
1.eclipse中安装插件,地址:http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/ ...
- SqlServer快速获得表总记录数(大数据量)
--第1种 执行全表扫描才能获得行数 SELECT count(*) FROM BUS_tb_UserGradePrice --第2种 执行扫描全表id不为空的,获得行数 select count(u ...
- Building a Simple User Interface(创建一个简单的用户界面)
对于一个android 应用程序,用户的图形界面通常是由View(视图)和ViewGroup(视图组)对象构成的层次结构. View(视图)对象通常是按钮或文本输入框这类UI小部件,ViewGroup ...