关于ValidatorEnable的工作机制

ASP.NET提供多个验证控件进行客户端验证.每个控件都触发相应的客户端的JavaScript进行数据验证。在ASP.NET的早期版本中,客户端Javascript库是公开进行修改。从ASP.NET 2.0开始,验证控件所使用的脚本库WebUIValidation.js成为一种System.Web程序集内嵌入资源。本文着眼于了解他们的工作机制和在页面的验证过程。 

验证控件的工作机制

为了演示asp.net验证过程,我们新建一个名叫SimpleValidationTest的简单web application.
1.用VS新建一个website:SimpleValidationTest
2. 

  1. <form id="form1" runat="server">  
  2. <div>  
  3.     <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>  
  4.     <asp:RequiredFieldValidator  
  5.         ID="RequiredFieldValidator1" runat="server" ErrorMessage="RequiredFieldValidator" 
  6.          ControlToValidate="TextBox1">  
  7.         </asp:RequiredFieldValidator>  
  8.     <asp:Button ID="Button1" runat="server" Text="Button" />  
  9.     <asp:ValidationSummary ID="ValidationSummary1"  runat="server" />  
  10. </div>  
  11. </form>  

当asp.net服务器端验证控件被使用时,在页面最终输出javascript代码来实现验证.asp.net所有的验证控件都继承自BaseValidator.在该类中注册通用的javascript脚本,输出通用的html.

当页面加入了asp.net验证控件.form将发生改变:

  1. onsubmit="javascript:return WebForm_OnSubmit();"  

在OnPreRender方法里,调用RegisterValidatorCommonScript来注册验证控件通用的javascript脚本,最终通过RegisterValidatorCommonScript函数来实现.

在render阶段,通过Page.ClientScript.RegisterOnSubmitStatement方法把onsubmit添加到form 上的.

  1. function WebForm_OnSubmit() {  
  2.    if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false)  
  3.       return false;  
  4.    
  5.    return true;  
  6. }  

WebForm_OnSubmit函数在form提交的时候被调用.如果页面无效,页面将无法提交.该条件由alidatorOnSubmit函数决定.

  1. var Page_ValidationActive = false;  
  2. if (typeof(ValidatorOnLoad) == "function") {  
  3.     ValidatorOnLoad();  
  4. }  
  5.    
  6. function ValidatorOnSubmit() {  
  7.     if (Page_ValidationActive) {  
  8.         return ValidatorCommonOnSubmit();  
  9.     }  
  10.     else {  
  11.         return true;  
  12.     }  
  13. }  

ValidatorOnLoad函数遍历validators数组,并初始化每项,设置Page_ValidationActive为true.当ValidatorOnSubmit被调用时,由于Page_ValidationActive为true,ValidatorCommonOnSubmit被调用.

  1. function ValidatorCommonOnSubmit() {  
  2.     Page_InvalidControlToBeFocused = null;  
  3.     var result = !Page_BlockSubmit;  
  4.     if ((typeof(window.event) != "undefined") && (window.event != null)) {  
  5.         window.event.returnValue = result;  
  6.     }  
  7.     Page_BlockSubmit = false;  
  8.     return result;  
  9. }  

缺省Page_BlockSubmit被设置为false.在页面客户端验证期间Page_BlockSubmit被设置为!Page_IsValid. 

深入理解页面验证 

  1. <script type="text/javascript">  
  2. <!--  
  3. var Page_ValidationSummaries =  new Array(document.getElementById("ValidationSummary1"));  
  4. var Page_Validators =  new Array(document.getElementById("RequiredFieldValidator1"));  
  5. // -->  
  6. </script>  

上面的代码显示ValidationSummary1控件对象被加入到Page_ValidationSummaries数组,RequiredFieldValidator1控件对象被加入到Page_Validators数组中.

Validator控件主要有controltovalidate, errormessage, evaluationfunction 和 initialvalue.controltovalidate的值对应要验证的控件ID.errormessage值是错误消息提示.initialvalue为初始值.evaluationfunction由服务器端验证控件的类型决定.

Validator type evaluationfunction
Required Field Validator RequiredFieldValidatorEvaluateIsValid
Range Validator RangeValidatorEvaluateIsValid
Custom Validator CustomValidatorEvaluateIsValid
Compare Validator CompareValidatorEvaluateIsValid

此前,我们提到到Page_IsValid决定页面是否有效。但是,那些函数设置该值以及这些函数如何被调用的?
使用我们上面的例子来显示这个过程. 我们监测button控件呈现HTML的过程.缺省情况下,每个按钮控件都会加上下面属性.

  1. onclick="javascript:WebForm_DoPostBackWithOptions(new 
  2.    WebForm_PostBackOptions("Button1", "", true, "", "", false, false))"  

上面的onclick属性由按钮的AddAttributesToRender方法添加.函数WebForm_DoPostBackWithOptions和WebForm_PostBackOptions在WebForms.js中.WebForm_DoPostBackWithOptions使用WebForm_PostBackOptions对象作为参数,调用Page_ClientValidate函数.Page_ClientValidate函数负责设置Page_IsValid变量的值.

下面显示Button控件点击完整的处理过程.

    1.  按钮被点击
    2.  函数WebForm_DoPostBackWithOptions被调用 

  1. function WebForm_DoPostBackWithOptions(options) {  
  2.     var validationResult = true;  
  3.     if (options.validation) {  
  4.         if (typeof(Page_ClientValidate) == 'function') {  
  5.             validationResult = Page_ClientValidate(options.validationGroup);  
  6.         }  
  7.     }  
  8.     if (validationResult) {  
  9.         if ((typeof(options.actionUrl) != "undefined") &&  
  10.                            (options.actionUrl != null) &&  
  11.                            (options.actionUrl.length > 0))  
  12.         {  
  13.             theForm.action = options.actionUrl;  
  14.         }  
  15.         if (options.trackFocus) {  
  16.             var lastFocus = theForm.elements["__LASTFOCUS"];  
  17.             if ((typeof(lastFocus) != "undefined") && (lastFocus != null)) {  
  18.                 if (typeof(document.activeElement) == "undefined") {  
  19.                     lastFocus.value = options.eventTarget;  
  20.                 }  
  21.                 else {  
  22.                     var active = document.activeElement;  
  23.                     if ((typeof(active) != "undefined") && (active != null)) {  
  24.                         if ((typeof(active.id) != "undefined") &&  
  25.                                            (active.id != null) &&  
  26.                                            (active.id.length > 0))  
  27.                         {  
  28.                             lastFocus.value = active.id;  
  29.                         }  
  30.                         else if (typeof(active.name) != "undefined") {  
  31.                             lastFocus.value = active.name;  
  32.                         }  
  33.                     }  
  34.                 }  
  35.             }  
  36.         }  
  37.     }  
  38.     if (options.clientSubmit) {  
  39.         __doPostBack(options.eventTarget, options.eventArgument);  
  40.     }  
  41. }  

    3. 函数Page_ClientValidate被调用

  1. function Page_ClientValidate(validationGroup) {  
  2.     Page_InvalidControlToBeFocused = null;  
  3.     if (typeof(Page_Validators) == "undefined") {  
  4.         return true;  
  5.     }  
  6.     var i;  
  7.     for (i = 0; i < Page_Validators.length; i++) {  
  8.         ValidatorValidate(Page_Validators[i], validationGroup, null);  
  9.     }  
  10.     ValidatorUpdateIsValid();  
  11.     ValidationSummaryOnSubmit(validationGroup);  
  12.     Page_BlockSubmit = !Page_IsValid;  
  13.     return Page_IsValid;  
  14. }  

    4. Page_IsValid 被设置.
    5. form 被提交
    6. onSubmit 事件被触发
    7. 返回WebForm_OnSubmit
    8. 返回 ValidatorOnSubmit
    9. 返回 ValidatorCommonOnSubmit
    10. 返回 !Page_BlockSubmit
    11. 返回 !(!Page_IsValid)

如果页面是有效的,将提交页面.如果页面无效,就不能提交页面,同时页面的validation summary 控件显示错误消息.函数ValidatorUpdateIsValid 和 ValidationSummaryOnSubmit负责这方面的功能. 

自定义验证控件 

在前面内容中,我们看到页面的验证过程内部机制。在下面的例子,我们将展示根据条件关闭或打开验证。在我们上面的示例程序中添加另一个文本框和自定义验证。验证函数决定验证的启用与否。该validateTextBox1函数接受两个参数,src和args。当在TextBox2中输入的值时,args.Value为true.RequiredFieldValidator1以编程方式被禁用。这是通过利用内置的ValidatorEnable功能来实现的.它需要这两个参数:验证器的名称和一个布尔型标志启用/禁用。自定义验证器的errormessage属性使用代码动态改变.根据用户输入,如果args.IsValid为false则页面无法提交。 

  1. <html xmlns="http://www.w3.org/1999/xhtml" >  
  2. <head runat="server">  
  3.     <title>Understanding .NET Validation</title>  
  4. <script type="text/javascript">  
  5. function validateTextBox1(src, args)  
  6. {  
  7.     if (args.Value == "true")  
  8.     {  
  9.         ValidatorEnable(RequiredFieldValidator1, false);  
  10.         src.errormessage = "TextBox1 required field validator is disabled";      
  11.     }  
  12.     else  
  13.     {  
  14.         ValidatorEnable(RequiredFieldValidator1, true);  
  15.         src.errormessage = "Enter true, not '"+args.Value+"' to disable TextBox1 required field validator";  
  16.     }  
  17.      args.IsValid = false;    
  18. }  
  19. </script>  
  20. </head>  
  21. <body>  
  22.     <form id="form1" runat="server">  
  23.     <div>  
  24.     TextBox 1: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>  
  25.     <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"   
  26.           Text="*" ControlToValidate="TextBox1"  
  27.           Display="Dynamic"   
  28.           ErrorMessage="TextBox1 is required"></asp:RequiredFieldValidator>  
  29.        <br />  
  30.        Disable required field for TextBox1?     
  31.     <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>  
  32.     <asp:CustomValidator ID="CustomValidator1" runat="server"  
  33.           Text="*" ControlToValidate="TextBox2" Display="Dynamic"  
  34.           ErrorMessage="CustomValidator"  
  35.           ClientValidationFunction="validateTextBox1"  
  36.           ValidateEmptyText="True"></asp:CustomValidator>  
  37.     <asp:ValidationSummary ID="ValidationSummary1" runat="server" />  
  38.     <asp:Button ID="Button1" runat="server" Text="Button"  />  
  39.     </div>  
  40.     </form>  
  41. </body>  
  42. </html>  

你可能感兴趣的:(关于ValidatorEnable的工作机制)