在系统开发时,很多情况下都需要对实体进行验证,比如规定某个属性值不能为空,Email的格式或者电话号码的格式是否正确.这种验证不应该只在UI层进行,主要有以下几方面的考虑:
     1.如果每个层次都相互独立,就不能够完全相信传入数据的有效性.比如如果你的UI代码直接调用了业务层,那么就能够相信任何用户的输入.
     2. 因为每个层次都有可能有复用性.也就是使用环境可能不一样.比如你的Webservice调用了你的业务层,你的UI也调用你的业务层.那么你的验证放在哪?

所以,在一个企业级系统中,对业务数据进行有效验证是非常有必要的.我觉得一个好框架应该能够满足以下要求:
     1.能够以很方便的方式进行规则验证.一般有属性标识或者XML.
     2.不仅提供丰富的基础的规则验证,而且能够支持对验证直接进行灵活扩展,添加用户自定义规则.
     3.能够很容易插拨.
     4.能够满足在不同的层使用同样的验证规则进行验证.

到现在为止,我接触过Enterprise Library提供的Validation Application Block(http://www.codeplex.com/entlib)以及开源的验证框架Validation Framework(http://www.codeplex.com/ValidationFramework),NHibernate.Valiator都符合上面的要求,而且现在他们都提供了对MVC,WPF的支持,相当的不错.
    OK,有点跑题了,言归正传.前段时间在NHibernate Contrib看到NHibernate.Validator项目,它是一个从Hibernate.Validator移植过来的开源项目,其实它和上面的两个验证框架都非常相似,提供的支持和功能基本上也都差不多.NHibernate.Valiator不仅可以对ORM中的业务对象进行验证,它也可以脱离NHibernate单独使用.相同,企业库的Validation Application  Block和Validation Framework不仅可以对我们的业务对象验证,也可以通过事件与NHibernate整合.

好的,那就来详细介绍一下NHibernate.Validator:

一.下载配置
        首先下载NHibernate.Validator    http://sourceforge.net/project/showfiles.php?group_id=216446
        然后在你使用的项目中引用相应的dll

二. 配置
        NHibernate.Validator的配置有几种方法:
 1.在你的应用程序下面新建文件nhvalidator.cfg.xml,在这个文件中添加配置信息

 <?xml version="1.0" encoding="utf-8" ?>
<nhv-configuration xmlns='urn:nhv-configuration-1.0'> <property name='apply_to_ddl'>true</property> <property name='autoregister_listeners'>true</property> <property name='default_validator_mode'>UseXml</property> <mapping assembly='NHibernate.Validator.Demo.Model'/>
</nhv-configuration> 

2.程序的app/web.config中添加配置信息

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="nhv-configuration" type="NHibernate.Validator.Cfg.ConfigurationSectionHandler, NHibernate.Validator" />
</configSections>   <nhv-configuration xmlns='urn:nhv-configuration-1.0'>       <shared_engine_provider   class='NHibernate.Validator.Event.NHibernateSharedEngineProvider, NHibernate.Validator'/>
</nhv-configuration>   </configuration>

3.全部使用程序进行配置

NHVConfiguration nhvc = new NHVConfiguration();
nhvc.Properties[Environment.ApplyToDDL] = "false";
nhvc.Properties[Environment.AutoregisterListeners] = "true";
nhvc.Properties[Environment.ValidatorMode] = "UseAttribute";
nhvc.Mappings.Add(new MappingConfiguration("NHibernate.ValidatorDemo.Model", null));ValidatorEngine validator = new ValidatorEngine();
validator.Configure(nhvc);

其实,你如果默认的方式使用,你可以不进行上面的任何配置,直接就可以调用:

ValidatorEngine validator = new ValidatorEngine();
bool isValid = validator.IsValid(customer);

上面的设置中有autoregister_listeners属性就是设置Validator是否自动的监听NHibernate的内置事件PreInsertEvent和PreUpdateEvent,如果为True,就是在实体进行添加和更新前都会对实体进行验证(这里包括级联验证),如果验证没有通过则会发出异常信息. 其实你也可以通过配置手动的监听这两个事件,在你的Hibernate的配置信息中添加:

<hibernate-configuration>
...
<event type="pre-update">
<listener class="NHibernate.Validator.Event.ValidatePreUpdateEventListener, NHibernate.Validator"/>
</event>
<event type="pre-insert">
<listener class="NHibernate.Validator.Event.ValidatePreInsertEventListener, NHibernate.Validator"/>
</event>
...
</hibernate-configuration>

但是我们在哪里能够保证我们调用的ValidatorEngine在我们的应用程序中只有一个实例呢(包括上面的两个监听事件的处理),因为我们这个在不同的层中都要使用的.肯定要保证验证的一致性. (当然也可以不进行这个设置),其中的一个方法就是设置SharedEngineProvider,在上面的配置时添加:

<shared_engine_provider class='NHibernate.Validator.Event.NHibernateSharedEngineProvider, NHibernate.Validator'/>

我们先看一下ISharedEngineProvider接口,很简单,就一个方法:

        /// <summary>/// Contract for Shared EngineP rovider/// </summary>public interface ISharedEngineProvider{/// <summary>/// Provide the shared engine instance./// </summary>/// <returns>The validator engine.</returns>ValidatorEngine GetEngine();}

然后是默认的NHibernateSharedEngineProvider怎么实现这个接口的:

 public class NHibernateSharedEngineProvider : ISharedEngineProvider{private static readonly ValidatorEngine ve = new ValidatorEngine();// Explicit static constructor to tell C# compiler not to mark type as before field initstatic NHibernateSharedEngineProvider(){}#region ISharedEngineProvider Memberspublic ValidatorEngine GetEngine(){return ve;}#endregion}

可以看到,其实也很简单,不过这样的话这里会不会有多线程问题呢?不过这里即使有多线程问题,我觉得这也没有必要.
       4.在使用IOC容器的系统和Web环境下,最好重新实现自己的SharedEngineProvider.不过,在这里介绍怎么在spring.net中配置NHibernate.Validator,并且能够使用DI直接使用声明的Validator对象.因为没有找到能够自动可以注入的ValidatorEngine,我自己实现了一个:

      public class NHValidatorObject : IFactoryObject, IInitializingObject{#region Fieldsprivate ValidatorEngine validator;private IMessageInterpolator interpolator;private ValidatorMode defaultMode;private bool applyToDDL;private bool autoRegisterListeners;private string sharedEngineProviderClass;private string[] mappingAssemblies;#endregion/// <summary>/// Default MessageInterpolator/// </summary>public IMessageInterpolator Interpolator{set { interpolator = value; }}/// <summary>/// Default Mode to construct validators/// </summary>public ValidatorMode DefaultMode{set { defaultMode = value; }}/// <summary>/// Database schema-level validation enabled/// </summary>public bool ApplyToDDL{ set { applyToDDL = value; }}/// <summary>/// NHibernate event-based validation/// </summary>public bool AutoRegisterListeners{set { autoRegisterListeners = value; }}public string SharedEngineProviderClass{set { sharedEngineProviderClass = value; }}/// <summary>/// Sets the assemblies to load that contain mapping files./// </summary>/// <value>The mapping assemblies.</value>public string[] MappingAssemblies{set { mappingAssemblies = value; }}/// <summary>/// Return the  validator/// </summary>/// <returns>The singleon validator factory.</returns>public object GetObject(){return validator;}/// <summary>/// Return the type/// </summary>/// <value>The type created by this factory</value>public System.Type ObjectType{get{return validator.GetType();}}/// <summary>/// Returns true/// </summary>/// <value>true</value>public bool IsSingleton{get{return true;}}/// <summary>/// Initialize validator  for the given or the/// default location./// </summary>public virtual void AfterPropertiesSet(){NHVConfiguration config = new NHVConfiguration();config.Properties.Add(Environment.ApplyToDDL,applyToDDL.ToString());config.Properties.Add(Environment.AutoregisterListeners,autoRegisterListeners.ToString());config.Properties.Add(Environment.ValidatorMode, defaultMode.ToString());foreach(string assembly in  mappingAssemblies){config.Mappings.Add(new MappingConfiguration(assembly,null));}validator = new ValidatorEngine();validator.Configure(config);}

然后在配置文件中声明对象,并且设置属性:

           <object id="NHValidator" type="Demo.NHValidatorObject,Demo" singleton="true">        <property name="ApplyToDDL" value="true"></property>        <property name="AutoRegisterListeners" value="true"></property>        <property name="DefaultMode" value="UseXml"></property>        <property name="MappingAssemblies">            <list>                <value>Demo.Model</value>            </list>        </property>    </object>

这样,你就要在你的任何一个层次中从applicationContext或者是通过依赖注入获取ValidatorEngine来完成实体验证了.
三.使用
采用属性定义的方式:

public class Customer{
[Length(Min = 3, Max = 20)]
public string FirstName{ get; set; }
[Length(Min=3, Max = 60)]
public string LastName { get; set; }
[CreditCardNumber]
public string CreditCard { get; set;}
}

采用XML映射文件的方式:(注意这里文件要为嵌入式资源,后面要以.nhv.xml结尾)

<nhv-mapping xmlns="urn:nhibernate-validator-1.0">
<class name="Demo.Customer,Demo">
<property name="FirstName">
<length min="3" max="20"/>
</property>
<property name="LastName"> <length min="3" max="60"/>
</property>
<property name="CreditCard">
<creditcardnumber/>
</property>
</class>
</nhv-mapping>

而且,NHibernate.Validator还支持以上两种方法混合使用.那我们再看一下怎么扩展自己的验证规则,首先先实现IValidator:

public class PhoneValidator : IValidator{  public bool IsValid(object value) {        Regex regex = new Regex(@"^[2-9]\d{2}-\d{3}-\d{4}$");     if (value == null)return true;      return regex.IsMatch(value.ToString());   }
}

然后是对应的属性标识:

[AttributeUsage(AttributeTargets.Field AttributeTargets.Property)]
[ValidatorClass(typeof(PhoneValidator))]
public class PhoneAttribute : Attribute, IRuleArgs{  private string message = string.Empty;   public string Message    {     get { return message; }     set { message = value; }  }
}

四.资料
1.NHibernate Validator 1.0.0 Documentation http://nhforge.org/wikis/validator10/nhibernate-validator-1-0-0-documentation.aspx
2.S#arp Architecture (Castle+AcitiveRecord+NHibernate.Validator)http://groups.google.com/group/sharp-architecture?hl=en
3.NHibernate.Validator - ASP.NET MVC http://www.pnpguidance.net/post/NHibernateValidatorTutorialValidateBusinessObjectsMVC.aspx
4.Diving in NHibernate.Validator http://fabiomaulo.blogspot.com/2009/02/diving-in-nhibernatevalidator.html
5.NHibernate Validator http://www.codinginstinct.com/2008/05/nhibernate-validator.html

作者:孤独侠客(似水流年)
出处:http://lonely7345.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/lonely7345/archive/2009/03/15/1412159.html

NHibernate.Validator 实体验证框架相关推荐

  1. @Validated和@Valid区别:Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated...

    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范,是标准JSR-303的一个变种),javax提供了@Valid(标准JSR- ...

  2. .Net Validator验证框架 [ .Net | Validator Framework | Attribute ]

    引: 具体地址忘记了,我是以前存在window live spaces 现在搬过来备份 (该文章在代码范例上有些说明不全,看附件来补充对 C# Attribute 的应用) 前言 简单易用是.Net ...

  3. jquery. Validator验证框架ajax返回json数据

    今天在使用jquery. Validator验证框架的过程中遇到了一个这个的问题: 我需要动态的去验证注册邮箱是否已经存在了,所以需要用到ajax请求来解决该问题.但在使用该验证框架的ajax异步请求 ...

  4. Hibernate 验证框架validator

    通常前端数据与后端交互CRUD都用到同一个类,那如何控制每一个操作类型的验证呢?多的不说了直接贴代码 1.依赖支持 <!-- hibernate 验证框架validator --> < ...

  5. Validator验证框架

     5.4  Validator验证框架 Struts1.1及以上版本,在提供了动态ActionForm的同时,配合数据验证的需要,还提供了表单输入自动验证的功能,即使用Validator验证框架. ...

  6. 你必须了解的反射——反射来实现实体验证

    开发工作中,都会需要针对传入的参数进行验证,特别是针对实体进行验证,确保传入的参数格式正确.这里做了一个非常简单的组件进行验证.抛砖引玉,让大家深入思考下反射的应用. 需求 日常开发,都是通过API进 ...

  7. Struts2(十二)使用验证框架验证数据较验

    一.数据验证 1.1.为什么要进行数据验证 对数据的合法性进行检查,只允许合法的数据进入应用程序 1.2.在哪里实现数据验证 客户端验证: 数据提交前在客户端验证 可使用JavaScript或者JQu ...

  8. java oval_Java开源可扩展数据验证框架之OVAL

    Java开源验证框架Oval是一个可扩展的Java对象数据验证框架,功能强大使用简单,验证规则可通过配置文件.注解等方式进行设置,规则的编写可以使用纯Java.JavaScript .Groovy . ...

  9. JS验证框架的使用方法

    今天着重介绍的是JS验证框架在Java Web项目中的应用, JSValidation要去http://cosoft.org.cn/projects/jsvalidation中下载最新版本. JSVa ...

最新文章

  1. vim设置行号等一系列配置
  2. 基于深度法向约束的稀疏雷达数据深度补全(商汤科技和香港大学联合提出)
  3. 以太坊开发(二)使用Ganache CLI在私有链上搭建智能合约
  4. linux内核参数优化 for 高并发服务器
  5. mysql校对规则设计编码命令
  6. WIndows下AppAche服务中调试php页面出现警告:Call to undefined function mysql_connect()
  7. PHP 实现归并排序算法
  8. c++小项目_编程初学者的练手小项目(Pythonamp;C/C++)
  9. linux启动mqtt_linux下安装MQTT服务器 - EMQTT
  10. 如何构建一套高可用的 APP 消息推送平台
  11. Java在Windows下导出xml文件到Linux服务器上
  12. windows2003密码忘记了该如何处理
  13. Response 与 Cookie
  14. 使用xlsx.core.min.js进行导入(表格)导出(Excel)功能
  15. ET框架---ClientFrameComponent学习笔记
  16. 软件开发者的软实力:沟通与协作
  17. 运动目标检测_帧差法
  18. 科技小科普】物联网的八大核心技术
  19. ZOOMIT的使用方法
  20. 科技兴关,荣联与天津海关共建基因组数据库及分析平台

热门文章

  1. C语言再学习--关键字
  2. docker 无法正常启动或版本信息会报错 Cannot connect to the Docker daemon at
  3. linux pppd源码下载_pppd源代码分析
  4. adb命令实现一些有趣的功能
  5. PaddlePaddle文本卷积实现情感分类和微博女友情绪监控AI
  6. 如何进入npm_如何用docsify在Github搭建自己的知识文档?
  7. python字典中append_零基础入手!Python中字典与集合的使用指南
  8. python能做哪些单机游戏好玩_【单机游戏】可以快速用Python进行数据分析的几个小技巧_玩得好游戏攻略...
  9. todo文件说明已停止工作_番茄ToDo,一款颜值功能兼备的番茄钟。
  10. 程序包android.support.annotation不存在_我不知道我不了解的Redis知识