企业库 验证模块的 javascript 解决方案
Enterprise Library Validation block For javascript
开始接触 enterprise library 5 是刚进公司那会。我花了两周时间把从企业库提供的功能走马观花的过了一遍。
之后,在我们的代码里用的最多的就是数据库,缓存用了一点点。
当初就想把验证这块给用上,但是搜了很多网页,没有找到如何用 javascript 来使用 VAB (Validation Block) 的。
其实我的想法很简单,能把配置文件中的验证规则提取出来就行。无奈很长一段时间里,我都没有找到这种方法。在 entlib.codeplex.com 和 stackoverflow 里也问过,跟本就没人回复!不知道是不是 VAB 真的不支持 javascript.
前两周,无意间搜到这个:
不过是用于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:'' } ]
有兴趣可以猛戳这个地址:
这个项目基于 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 没有测到。
如果您代为测试,请不要吝惜您的笔墨。
谢谢。
推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架