Enterprise Library Validation block For javascript

http://vabtojs.codeplex.com/

开始接触 enterprise library 5 是刚进公司那会。我花了两周时间把从企业库提供的功能走马观花的过了一遍。

之后,在我们的代码里用的最多的就是数据库,缓存用了一点点。

当初就想把验证这块给用上,但是搜了很多网页,没有找到如何用 javascript 来使用 VAB (Validation Block) 的。

其实我的想法很简单,能把配置文件中的验证规则提取出来就行。无奈很长一段时间里,我都没有找到这种方法。在 entlib.codeplex.com 和 stackoverflow 里也问过,跟本就没人回复!不知道是不是 VAB 真的不支持 javascript.

前两周,无意间搜到这个:

http://elvalweb.codeplex.com/

不过是用于MVC的,看了一下它是如何从配置文件中提取配置的代码,豁然开朗。

早在07年的时候,我就写过一个 FormValidation 的 js 代码,直到现在我还在不断的修改,可以说,它以经相当完善了。这次我就是把 VAB 的验证器提取为 FormValidation 使用的规则格式:

[
	{ name:'txtName' , type:'And' , msg:'' , tag:'' , subRule:[
		{ name:'txtName' , required:true , type:'Length' , min:2 , includeMin:true , max:20 , includeMax:true , msg:'' , tag:'' },
		{ name:'txtName' , required:true , type:'Regex' , regex:/^(xling|admin)$/ , negated:true , msg:'' , tag:'' }
		]
	 },
	{ name:'txtBirthday' , required:true , type:'RelativeDateTime' , min:-50 , minUnit:'' , includeMin:true , max:-10 , includeMax:true , maxUnit:'' , serverTime:'2011-07-16 16:13:19' , msg:'' , tag:'' },
	{ name:'txtEmail' , type:'Or' , msg:'Invalid email address. (Optional)' , tag:'' , subRule:[
		{ name:'txtEmail' , required:false , type:'Regex' , regex:/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/ , msg:'' , tag:'' }
		]
	 },
	{ name:'txtProject1' , required:true , type:'Length' , min:2 , includeMin:true , max:20 , includeMax:true , msg:'' , tag:'' },
	{ name:'txtProject2' , required:true , type:'Length' , min:2 , includeMin:true , max:20 , includeMax:true , msg:'' , tag:'' },
	{ name:'txtScore1' , required:true , type:'Range' , min:0 , includeMin:true , max:150 , includeMax:true , msg:'' , tag:'' },
	{ name:'txtScore2' , required:true , type:'Range' , min:0 , includeMin:true , max:150 , includeMax:true , msg:'' , tag:'' }
]

有兴趣可以猛戳这个地址:

http://vabtojs.codeplex.com/

这个项目基于 EntLib 5.0 里的验证模块(VAB)。它实现了VAB到 javascript 的转换。

它首先会跟据配置文件中的验证规则,生成对应的 javascript 验证规则,并配合 EntLibValidation.js 来验证用户输入, 注意:不是用 ajax 验证 。

目前支持以下几种验证器:

  • And Composite
  • Or Composite
  • Contains Characters
  • Date Time Range
  • Domain
  • Not null
  • Object
  • Property Comparison
  • Range
  • Regex
  • Relative Date Time
  • String Length

不支持以下几种验证器:

  • Custom
  • Enum Conversion
  • Object collection
  • Type Conversion
And and Or Composite Validator 
这两个验证器把子验证器提取为子规则
Domain Validator
呈现为正则验证器
Notnull Validator 
如果在 And 和 Or 规则的子规则中,存在 not null 验证器,且它的 negated 属性是 true, 那么其它子验证器将会添加一个 required = false 的规则。
Object Validator
Object 验证器跟据 target ruleset ,提取子验证器,并合并到主线上。
Relative DateTime Validator 
增加了一个 serverTime 的规则。这个规则如果省略,将会以客户端的当前时间为为基准。
如何使用:
1,绑定:
protected void Page_Load(object sender , EventArgs e) {
            var builder = new MapBuilder<StudentEntity> ( );
            builder.Map ( l => l.Name , txtName )
                .Map ( l => l.Birthday , txtBirthday )
                .Map ( l => l.Email , txtEmail )
                //.Map(l=>l.Sex, rblSex)
                .Map ( l => l.Scores.Project , txtProject1 )
                .Map ( l => l.Scores.Score , txtScore1 )
                .Map ( l => l.Scores.Project , txtProject2 )
                .Map ( l => l.Scores.Score , txtScore2 );

            this.Rules = ValidationHelper.GetClientRules ( typeof ( StudentEntity ) , "AddStudent" , builder.Maps );
        }
2,引用 js 文件:
<script src="js/EntLibValidation.js" type="text/javascript"></script>
3,修改 Form (不限于这种方式)
<form id="form1" runat="server" onsubmit="return validate(this)">
4, js 代码
<script>
        var rule = <%= this.Rules %> ;

        rule.push({ name:'txtReEmail' , required:true , type:'Repeat' , to:'txtEmail', operator:'==' , msg:'' , tag:'' });
        rule.push({ name:"rblSex", type:"Group", required:true , min:1, noSelected:'Shemale' , msg:"请选盾性别,不能为人妖" });


        var customValidHelper = {};
        (function(o){

	        o.pass = function(obj,rule){

                if(obj.length != undefined && obj.length > 0)
                    obj = obj[obj.length - 1];

                if(FormValidateForEntLib.allPass(obj)){
		            try{
			            document.body.removeChild(obj.errorTip);
			            obj.errorTip = null
		            }catch(e){}
                }
	        }

	        o.unPass = function(obj,rule){

                if(obj.length != undefined && obj.length > 0)
                    obj = obj[obj.length - 1];

		        if(!obj.errorTip){
			        var tmp = document.createElement("DIV");
			        tmp.className = "tip shadow radius";
			        document.body.appendChild(tmp);
			        obj.errorTip = tmp;
			        obj.errorTip.innerHTML = "<span class='warnning'></span>" + FormValidateForEntLib.getMessage( rule );
		        }else{
			        obj.errorTip.innerHTML = "<span class='warnning'></span>" + FormValidateForEntLib.getMessage( rule );
		        }

                var tipFollow;
                if(rule.tag && CTSZ.$(rule.tag)){
                    tipFollow = CTSZ.$(rule.tag);
                }else{
                    tipFollow = obj;
                }

                var pos = CTSZ.getAbsPos(tipFollow);
                CTSZ.css(obj.errorTip, {left:pos.x + tipFollow.offsetWidth , top:pos.y - 8});

	        }

        })(customValidHelper);

        var va = FormValidateForEntLib.getInstance();
        var validate = function (form) {
            var f = va.validate(form, rule, 3, customValidHelper.pass, customValidHelper.unPass);
            return f !== false;
        }        
    </script>
这里的 customValidHelper 可随便修改
提供了4种验证模式:
1, Check all , then alert all error. 全部检查,并alert
2, Check one by one , if have error , stop check . 一个一个检查,如果有错误,停止检查。
3, Check all , if pass , call onPassFun, if failed, call onUnpassFun 调用自定义事件 onPassFun验证通过时调用,onUnpassFun未通过时调用。
4, Check one by one , when pass or unpass invokde callback. 同3,但是当验证不通过时,立即停止向下检查。
目前 javascript 文件改动比较大,还存在一些 BUG 没有测到。
如果您代为测试,请不要吝惜您的笔墨。
谢谢。

作者: xling 发表于 2011-07-16 17:12 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架