最近转到系统框架和控件开发工作,仔细研究了.net框架和控件,在MSDN上看了两天总觉得对asp.net控件机制理解不深,果然在实现TextBox自验证功能时遇到了问题,开始自己实现写入JS脚本到客户端实现客户端验证,在服务器端继承了接口IValidator实现服务器验证,代码:
public class ExTextBox : TextBox, IValidator {
private bool _valid = true;
private string _errorMessage = "";
public bool IsValid {
get { return _valid; }
set { _valid = value; }
}
public string ErrorMessage {
get { return _errorMessage; }
set { _errorMessage = value; }
}
//服务器验证实现代码
public void Validate()
{
//在这里设置IsValid值
}
}
}
验证控件是在初始化期间加载他们本身的,IValidators接口主要用来注册他们自己,所以我们需要使用覆盖的方法重新实现OnInit和OnUnload事件,以便我们能从页面中的验证控件集合中添加或者删除它们
protected override void OnInit(EventArgs e) {
base.OnInit(e);
Page.Validators.Add(this);
}
protected override void OnUnload(EventArgs e) {
if (Page != null) {
Page.Validators.Remove(this);
}
base.OnUnload(e);
}
这样就实现了服务器端验证,很简单吧,但后来发现了个问题,当客户端验证失败时不能阻止表单的提交,可以用JS阻止提交,但当Button的CausesValidation属性设为false时也阻止了表单提交,怎么样才能实现和asp.net验证框架“兼容”呢,后来在网上找到个工具Reflector可以查看.net有源代码,真是开心,用这个工具.net类库源代码一目了然,然后我仔细查看了asp.net的验证控件,发现要使用客户端验证框架只需编写以下两个方法:
//注册客户端验证脚本
protected void RegisterValidatorCommonScript() { if (!this.Page.IsPartialRenderingSupported) { if (!this.Page.ClientScript.IsClientScriptBlockRegistered(typeof(BaseValidator), "ValidatorIncludeScript")) { this.Page.ClientScript.RegisterClientScriptResource(typeof(BaseValidator), "WebUIValidation.js"); this.Page.ClientScript.RegisterStartupScript(typeof(BaseValidator), "ValidatorIncludeScript", "/r/nvar Page_ValidationActive = false;/r/nif (typeof(ValidatorOnLoad) == /"function/") {/r/n ValidatorOnLoad();/r/n}/r/n/r/nfunction ValidatorOnSubmit() {/r/n if (Page_ValidationActive) {/r/n return ValidatorCommonOnSubmit();/r/n }/r/n else {/r/n return true;/r/n }/r/n}/r/n ", true); this.Page.ClientScript.RegisterOnSubmitStatement(typeof(BaseValidator), "ValidatorOnSubmit", "if (typeof(ValidatorOnSubmit) == /"function/" && ValidatorOnSubmit() == false) return false;"); } } else { ValidatorCompatibilityHelper.RegisterClientScriptResource(this, typeof(BaseValidator), "WebUIValidation.js"); ValidatorCompatibilityHelper.RegisterStartupScript(this, typeof(BaseValidator), "ValidatorIncludeScript", "/r/nvar Page_ValidationActive = false;/r/nif (typeof(ValidatorOnLoad) == /"function/") {/r/n ValidatorOnLoad();/r/n}/r/n/r/nfunction ValidatorOnSubmit() {/r/n if (Page_ValidationActive) {/r/n return ValidatorCommonOnSubmit();/r/n }/r/n else {/r/n return true;/r/n }/r/n}/r/n ", true); ValidatorCompatibilityHelper.RegisterOnSubmitStatement(this, typeof(BaseValidator), "ValidatorOnSubmit", "if (typeof(ValidatorOnSubmit) == /"function/" && ValidatorOnSubmit() == false) return false;"); } } //注册到客户端难组,以便ValidationSummary 收集验证消息 protected virtual void RegisterValidatorDeclaration() { string arrayValue = "document.getElementById(/"" + this.ClientID + "/")"; if (!this.Page.IsPartialRenderingSupported) { this.Page.ClientScript.RegisterArrayDeclaration("Page_Validators", arrayValue); } else { ValidatorCompatibilityHelper.RegisterArrayDeclaration(this, "Page_Validators", arrayValue); ValidatorCompatibilityHelper.RegisterStartupScript(this, typeof(BaseValidator), this.ClientID + "_DisposeScript", string.Format(CultureInfo.InvariantCulture, "/r/ndocument.getElementById('{0}').dispose = function() {{/r/n Array.remove({1}, document.getElementById('{0}'));/r/n}}/r/n", new object[] { this.ClientID, "Page_Validators" }), true); } } 微软的验证框架还是很强大,详细可以查看asp.net验证控件生成的客户端源码。 |
好了,就写这么多了,我个人是理论主义者,我希望大家理解它的运行原理,然后自己实现逻辑代码。 |