博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET:创建Linked ValidationSummary, 深入理解ASP.NET的Validation
阅读量:6464 次
发布时间:2019-06-23

本文共 24284 字,大约阅读时间需要 80 分钟。

我想对于ASP.NET的Validator控件已经熟悉的不能再熟悉了。我们 已经习惯了用Validator控件来验证我们在表单的输入,并通过ValidationSummary来输出我们为Validator控件设置的Error message。不知道大家有没想过进一步改进一下我们的Validation来改善我们的User Experience。比如,在ValidationSummary输出一个Link连接到对应的控件,而不是显示单纯的Error message。

比如在上图中,是一个典型的Login的Page。我们有两个必填的字段:User name和Password。为此我定义两个RequiredFieldValidator。他们的Error message分别为:”User name is mandatory!”和”Password is mandatory!”。在未输入任何值得前提下Click “Sign in”按钮,Error Message被显示在ValidationSummary上面。不过和传统的Error message不同,显示在ValidationSummary上的实际上是两个链接,Click对应的Error message,光标会设置到对应的Textbox上。比如上图所示:单击”User name is mandatory!”,光标回到User name对应的Texbox

一、首先来看看aspx

现在我们来简单叙述上面的效果是如果实现的,在开始之前我想说的是,方法非常简单—或许你已经猜到了。下面是上面创建的用于登录的Web页面的HTML。

1: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
2: 
3: 
4: 
5:     Login
6:     
7:         body{}{font-family:Verdana; font-size:10px}
8:         table{}{width:300px}
9:         table tr{}{height:30px}
10:         table td.firstColumn{}{width:100px; text-align:right}
11:         table td.secondColumn{}{ text-align:left}
12:         table span.asterisk{}{color:red}
13:         table .textbox{}{width:150px; border:solid 1px #999999}
14:         table .button{}{background-color: #00cc66;border:solid 1px #999999}
15:         ul li{}{margin-bottom:5px}
16:         ul li a{}{color:red; text-decoration:none}
17:         ul li a:hover{}{text-decoration:underline}
18:    
19:
20:    
1: 
2:        function setFocus(control) {
3:            var controlToValidate = document.getElementById(control);
4:            controlToValidate.focus();
5:        }
6:
7:
</
script
>
21: 
22: 
23:     
24:         
25:             
26:                 
27:                     
28:                         
29:                     
30:                 
31:                 
32:                     
33:                         User Name:  *
34:                     
35:                         
36:                         
37:                         
38:                     
39:                 
40:                 
41:                     
42:                         Password:  *
43:                     
44:                         
45:                         
46:                     
47:                 
48:                 
49:                     
50:                         
   
51:                         
52:                             CssClass="button" />
53:                     
54:                 
55:             
56:         
57:     
58: 
59: 

在看到了上面的登录界面之后再看看上面的HTML,结构清晰得一目了然。所以我就不再进一步解释了。在这里我只需要提提定义在aspx的一段javascript函数:setFocus。通过它把focus设置到指定的控件。

1: 
2:        function setFocus(control)
3:        {
4:            var controlToValidate = document.getElementById(control);
5:            controlToValidate.focus();
6:        }
7: 

二、接着我们来看看后台代码

看完了HTML,我们来看看该登录Web页面的后台代码。下面的代码片断为你展示了该Web页面背后的所有代码,所有的机关就存在于Web页面的Load时间处理方法Page_Load方法中。

1: public partial class Login : System.Web.UI.Page
2: {
3:     protected void Page_Load(object sender, EventArgs e)
4:     {
5:         if (this.IsPostBack)
6:         {
7:             return;
8:         }
9: 
10:         this.rqfUserName.ErrorMessage = string.Format("{0} is mandatory!", "User name");
11:         this.rqfPassword.ErrorMessage = string.Format("{0} is mandatory!", "Password");
12:         this.ctmUserName.ErrorMessage = "Such a user has not registered!";
13: 
14:         this.MakeClickableErrorMessage();
15:     }
16: 
17:     private void MakeClickableErrorMessage()
18:     {
19:         foreach (BaseValidator validator in this.Validators)
20:         {
21:             if (validator.ControlToValidate == string.Empty)
22:             {
23:                 continue;
24:             }
25:             string clientID = this.FindControl(validator.ControlToValidate).ClientID;
26:             string script = string.Format("{1}", clientID, validator.ErrorMessage);
27:             validator.ErrorMessage = script;
28:         }
29:     }
30: 
31:     protected void ctmUserName_ServerValidate(object source, ServerValidateEventArgs args)
32:     {
33:         if (this.txtUserName.Text.Trim() != "adm")
34:         {
35:             args.IsValid = false;
36:             return;
37:         }
38: 
39:         args.IsValid = true;
40:     }
41: }

上面代码也简单得一塌糊涂,除了MakeClickableErrorMessage这个方法,其他的都不值一提。显示在ValidationSummary中原本简单的literal error message就是通过上面的这个MakeClickableErrorMessage方法转变成超链接的。

1: private void MakeClickableErrorMessage()
2:     {
3:         foreach (BaseValidator validator in this.Validators)
4:         {
5:             if (validator.ControlToValidate == string.Empty)
6:             {
7:                 continue;
8:             }
9:             string clientID = this.FindControl(validator.ControlToValidate).ClientID;
10:             string script = string.Format("{1}", clientID, validator.ErrorMessage);
11:             validator.ErrorMessage = script;
12:         }
13:     }

在上面的代码中,我遍历page中的每个验证控件。如果该验证具有对应ControlToValidate属性(对于一个验证控件来说,ControlToValidate并非一个必需的属性,如果没有指定该属性,其值为空字符串),直接进入下一个循环。然后我把原来只是弹出的文本转变成一个<a></a>块,然后再将其重新赋值给对应的Validator contorl的ErrorMessage property。比如对于rqfUserName RequiredFieldValidator来说,原来的Error message是”User name is mandatory!”,那么现在的Error message变成了:

上面只是一个简单的小窍门,我们以此为例,来进一步介绍ASP.NET如何进行验证的的。为了简单起见,在这里我没法讨论所有的验证控件。只介绍和这两种验证控件的处理流程。

三、ASP.NET是如何实现客户端验证的?

我们通过IE来浏览上面的Page,我们可以通过查看源文件得到最终呈现出来的Web页面的HTML。对于上面提到的登录页面,在客户端呈现出来的HTML如下面的HTML所示。

1: 
2: 
3: 
4:     Login
5: 
6:     
7:         body{}{font-family:Verdana; font-size:10px}
8:         table{}{width:300px}
9:         table tr{}{height:30px}
10:         table td.firstColumn{}{width:100px; text-align:right}
11:         table td.secondColumn{}{ text-align:left}
12:         table span.asterisk{}{color:red}
13:         table .textbox{}{width:150px; border:solid 1px #999999}
14:         table .button{}{background-color: #00cc66;border:solid 1px #999999}
15:         ul li{}{margin-bottom:5px}
16:         ul li a{}{color:red; text-decoration:none}
17:         ul li a:hover{}{text-decoration:underline}
18:    
19:    
1: 
2:        function setFocus(control) {
3:            var controlToValidate = document.getElementById(control);
4:            controlToValidate.focus();
5:        }
6:
</
script
>
1:
2: 
3: 
4:     
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12:     var theForm = document.forms['form1'];
13:     if (!theForm) {
14:         theForm = document.form1;
15:     }
16:     function __doPostBack(eventTarget, eventArgument) {
17:         if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
18:             theForm.__EVENTTARGET.value = eventTarget;
19:             theForm.__EVENTARGUMENT.value = eventArgument;
20:             theForm.submit();
21:         }
22:     }
23: // -->
</
script
>
1:
2: 
1: 
2: 
1: 
2: 
3: 
4:     function WebForm_OnSubmit() {
5:         if (typeof (ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
6:         return true;
7:     }
8: // -->
</
script
>
1:
2:         
3:             
4:                 
5:                     
6:                         
7: 
8:                     
9:                 
10:                 
11:                     
12:                         User Name:  *
13:                     
14:                         
15:                         
16:                         
17:                     
18:                 
19:                 
20:                     
21:                         Password:  *
22:                     
23:                         
24:                         
25:                     
26:                 
27:                 
28:                     
29:                            
30:                         
31:                     
32:                 
33:             
34:         
35: 
36: 
37:     var Page_ValidationSummaries = new Array(document.getElementById("vldLogin"));
38:     var Page_Validators = new Array(document.getElementById("rqfUserName"), document.getElementById("ctmUserName"), document.getElementById("rqfPassword"));
39: // -->
</
script
>
1:
2:
3: 
4: 
5:     var rqfUserName = document.all ? document.all["rqfUserName"] : document.getElementById("rqfUserName");
6:     rqfUserName.controltovalidate = "txtUserName";
7:     rqfUserName.errormessage = "User name is mandatory!";
8:     rqfUserName.display = "None";
9:     rqfUserName.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
10:     rqfUserName.initialvalue = "";
11:     var ctmUserName = document.all ? document.all["ctmUserName"] : document.getElementById("ctmUserName");
12:     ctmUserName.controltovalidate = "txtUserName";
13:     ctmUserName.errormessage = "Such a user has not registered!";
14:     ctmUserName.display = "None";
15:     ctmUserName.evaluationfunction = "CustomValidatorEvaluateIsValid";
16:     var rqfPassword = document.all ? document.all["rqfPassword"] : document.getElementById("rqfPassword");
17:     rqfPassword.controltovalidate = "txtPassword";
18:     rqfPassword.errormessage = "Password is mandatory!";
19:     rqfPassword.display = "None";
20:     rqfPassword.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
21:     rqfPassword.initialvalue = "";
22: // -->
</
script
>
1:
2: 
3:     
4: 
5: 
6: 
7:     var Page_ValidationActive = false;
8:     if (typeof (ValidatorOnLoad) == "function") {
9:         ValidatorOnLoad();
10:     }
11: 
12:     function ValidatorOnSubmit() {
13:         if (Page_ValidationActive) {
14:             return ValidatorCommonOnSubmit();
15:         }
16:         else {
17:             return true;
18:         }
19:     }
20: // -->
</
script
>
20:         
21: 
22: 

我们从中提取对验证有用的信息。首先我们会看到有两个JavaScript被引用:

1: 
2: 

这两个JavaScript由ASP.NET生成。尤其内容较多,在这里先不列出他们的内容,等下面真正要使用到其中定义的JavaScript 在列出来。我们现在姑且称它们为JavaScript1JavaScript2。在下面一段JavaScript中,为3个验证控件定义了3个客户端的对象,对象的名称和控件名称同名。并设置相关的属性:controltovalidate,errormessage,display,evaluationfunction。其中evaluationfunction为进行Validation的function的名称。

1: 
2: 
3:     var rqfUserName = document.all ? document.all["rqfUserName"] : document.getElementById("rqfUserName");
4:     rqfUserName.controltovalidate = "txtUserName";
5:     rqfUserName.errormessage = "User name is mandatory!";
6:     rqfUserName.display = "None";
7:     rqfUserName.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
8:     rqfUserName.initialvalue = "";
9:     var ctmUserName = document.all ? document.all["ctmUserName"] : document.getElementById("ctmUserName");
10:     ctmUserName.controltovalidate = "txtUserName";
11:     ctmUserName.errormessage = "Such a user has not registered!";
12:     ctmUserName.display = "None";
13:     ctmUserName.evaluationfunction = "CustomValidatorEvaluateIsValid";
14:     var rqfPassword = document.all ? document.all["rqfPassword"] : document.getElementById("rqfPassword");
15:     rqfPassword.controltovalidate = "txtPassword";
16:     rqfPassword.errormessage = "Password is mandatory!";
17:     rqfPassword.display = "None";
18:     rqfPassword.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid";
19:     rqfPassword.initialvalue = "";
20: // -->
21: 

我们还发现通过Javascript定义了两个Array对象:Page_ValidationSummaries和Page_Validators。这两个Array用于保存Page中的所有的ValidationSummary和Validator control

1: 
2: 
3: var Page_ValidationSummaries =  new Array(document.getElementById("vldLogin"));
4: var Page_Validators =  new Array(document.getElementById("rqfUserName"), document.getElementById("ctmUserName"), document.getElementById("rqfPassword"));
5: // -->
6: 

我们知道,所有的Validation操作都是在Click “Sign In” 按钮之后进行的。我们来看看,该按钮的onClick事件处理程序是如何定义的:

<
input
type
="submit"
name
="btnSignIn"
value
="Sign in"
onclick
="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(&quot;btnSignIn&quot;, &quot;&quot;, true, &quot;&quot;, &quot;&quot;, false, false))"
id
="btnSignIn"
class
="button"
 
/>

通过onclick事件,我们可以看到,一个命名为WebForm_DoPostBackWithOptions的javascript function被调用,该function接收一个称为WebForm_PostBackOptions类型的对象。该类型被定一个在JavaScript1中(还记得JavaScript1指的是什么吗? 上溯到第三段)。

1: function WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit) {
2:     this.eventTarget = eventTarget;
3:     this.eventArgument = eventArgument;
4:     this.validation = validation;
5:     this.validationGroup = validationGroup;
6:     this.actionUrl = actionUrl;
7:     this.trackFocus = trackFocus;
8:     this.clientSubmit = clientSubmit;
9: }

该对象具有这样的表述的是关于Postback context的一些信息,比如:

  • eventTarget:Event触发的control,当前为” btnSignIn”。
  • eventArgument:Event额外的参数, 当前为””。
  • validation:是否进行Validation,当前为true。
  • validationGroup:eventTarget 对应的Validation group,这是ASP.NET 2.0的新特性,当当前为””,因为我没有设置btnSignIn的ValidationGroup的property。
  • actionUrl:表单被提交的Url,就像asp中Form的action一样。ASP.NET 1.x不提供cross-page的提交,在2.0中提供了此功能,当前为””, 我没有进行cross-page的提交。
  • trackFocus:是否进行焦点追踪,当前为false。
  • clientSubmit:是否通过form submit导致Postback,当前为false。

我们再来看看WebForm_DoPostBackWithOptions,像WebForm_PostBackOptions一样,该function同样被定义在JavaScript1中。

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") && (options.actionUrl != null) && (options.actionUrl.length > 0)) {
10:             theForm.action = options.actionUrl;
11:         }
12:         if (options.trackFocus) {
13:             var lastFocus = theForm.elements["__LASTFOCUS"];
14:             if ((typeof(lastFocus) != "undefined") && (lastFocus != null)) {
15:                 if (typeof(document.activeElement) == "undefined") {
16:                     lastFocus.value = options.eventTarget;
17:                 }
18:                 else {
19:                     var active = document.activeElement;
20:                     if ((typeof(active) != "undefined") && (active != null)) {
21:                         if ((typeof(active.id) != "undefined") && (active.id != null) && (active.id.length > 0)) {
22:                             lastFocus.value = active.id;
23:                         }
24:                         else if (typeof(active.name) != "undefined") {
25:                             lastFocus.value = active.name;
26:                         }
27:                     }
28:                 }
29:             }
30:         }
31:     }
32:     if (options.clientSubmit) {
33:         __doPostBack(options.eventTarget, options.eventArgument);
34:     }
35: }

在开始的时候,调用Page_ClientValidate进行客户端验证。我们来着重分析上面的javascript,看看具体的流程。Page_ClientValidate被定义在Javascript2中。

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: }

上面的代码中,首先通过Page_Validators判断Page是否存在验证控件。我们在预先定义了Page_Validators 数组(还记得我们之前介绍的两个Array——Page_ValidationSummaries和Page_Validators吗?)。虽有遍历所有的验证控件,并调用ValidatorValidate方法执行每个验证控件的客户端验证。我们进一步看看ValidatorValidate又是如何定义的(ValidatorValidate定义在Javascript2中)。

1: function ValidatorValidate(val, validationGroup, event) {
2:     val.isvalid = true;
3:     if ((typeof(val.enabled) == "undefined" || val.enabled != false) && IsValidationGroupMatch(val, validationGroup)) {
4:         if (typeof(val.evaluationfunction) == "function") {
5:             val.isvalid = val.evaluationfunction(val);
6:             if (!val.isvalid && Page_InvalidControlToBeFocused == null &&
7:                 typeof(val.focusOnError) == "string" && val.focusOnError == "t") {
8:                 ValidatorSetFocus(val, event);
9:             }
10:         }
11:     }
12:     ValidatorUpdateDisplay(val);
13: }

首先通过IsValidationGroupMatch判断验证控件的ValidationGroup是否和触发Postaback的Control对应的ValidationGroup相互匹配。因为只有在匹配的前提下才进行相关验证控件的验证工作。然后调用验证控件的evaluationfunction function来进行验证。通过前面的分析,我们知道RequiredFieldValidator的evaluationfunction为RequiredFieldValidatorEvaluateIsValid,而CustomValidator的evaluationfunction为CustomValidatorEvaluateIsValid。我们来看看这两个function是如何定义的。他们都定义在Javascript2中。

  • RequiredFieldValidatorEvaluateIsValid:通过正则表达式验证是否具有有效输入
    1: function RequiredFieldValidatorEvaluateIsValid(val) {
    2:     return (ValidatorTrim(ValidatorGetValue(val.controltovalidate)) !=       ValidatorTrim(val.initialvalue))
    3: }
    4: function ValidatorGetValue(id) {
    5:     var control;
    6:     control = document.getElementById(id);
    7:     if (typeof(control.value) == "string") {
    8:         return control.value;
    9:     }
    10:     return ValidatorGetValueRecursive(control);
    11: }
    12: function ValidatorGetValueRecursive(control)
    13: {
    14:     if (typeof(control.value) == "string" && (control.type != "radio" || control.checked == true)) {
    15:         return control.value;
    16:     }
    17:     var i, val;
    18:     for (i = 0; i
    19:         val = ValidatorGetValueRecursive(control.childNodes[i]);
    20:         if (val != "") return val;
    21:     }
    22:     return "";
    23: }
    24: function ValidatorTrim(s) {
    25:     var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
    26:     return (m == null) ? "" : m[1];
    27: }

  • CustomValidatorEvaluateIsValid:实际上就是调用我们为CustomValidator设置的ClientValidationFunction
    1: function CustomValidatorEvaluateIsValid(val) {
    2:     var value = "";
    3:     if (typeof(val.controltovalidate) == "string") {
    4:         value = ValidatorGetValue(val.controltovalidate);
    5:         if ((ValidatorTrim(value).length == 0) &&
    6:             ((typeof(val.validateemptytext) != "string") || (val.validateemptytext != "true"))) {
    7:             return true;
    8:         }
    9:     }
    10:     var args = { Value:value, IsValid:true };
    11:     if (typeof(val.clientvalidationfunction) == "string") {
    12:         eval(val.clientvalidationfunction + "(val, args) ;");
    13:     }
    14:     return args.IsValid;
    15: }

在ValidatorValidate中,当我们通过调用各个验证控件的evaluationfunction来进行客户端端的验证后,对于没有通过验证的验证控件,通过调用ValidatorSetFocus设置相应控件的焦点。在这里就不在深入探讨了。接着通过调用ValidatorUpdateDisplay来根据我们制定的Display和不同浏览器,来设置错误消息的显示方式。

1: function ValidatorUpdateDisplay(val) {
2:     if (typeof(val.display) == "string") {
3:         if (val.display == "None") {
4:             return;
5:         }
6:         if (val.display == "Dynamic") {
7:             val.style.display = val.isvalid ? "none" : "inline";
8:             return;
9:         }
10:     }
11:     if ((navigator.userAgent.indexOf("Mac") > -1) &&
12:         (navigator.userAgent.indexOf("MSIE") > -1)) {
13:         val.style.display = "inline";
14:     }
15:     val.style.visibility = val.isvalid ? "hidden" : "visible";
16: }

实际上到现在为止,所有的验证工作已经完成。接下来我们来看看验证失败后相应的错误消息是如何显示的。所以我们要看看ValidatorUpdateDisplay的定义了。

分析完ValidatorValidate,我们在回到Page_ClientValidate上面。现在我们接着分析一下的执行流程。通过调用ValidatorValidate执行完各个验证控件的验证后,接着调用的是ValidatorUpdateIsValid()和ValidationSummaryOnSubmit(validationGroup)。ValidatorUpdateIsValid通过遍历每个验证控件来查看他们是否通过验证,最终确定这个页面是否通过验证。ValidationSummaryOnSubmit通过拼接字符串的形式在ValidationSummary显示对应的错误消息。这正是我们可以将错误消息写成超链接的原因所在。

1: function ValidatorUpdateIsValid() {
2:     Page_IsValid = AllValidatorsValid(Page_Validators);
3: }
4: function AllValidatorsValid(validators) {
5:     if ((typeof(validators) != "undefined") && (validators != null)) {
6:         var i;
7:         for (i = 0; i < validators.length; i++) {
8:             if (!validators[i].isvalid) {
9:                 return false;
10:             }
11:         }
12:     }
13:     return true;
14: }
15: function ValidationSummaryOnSubmit(validationGroup) {
16:     if (typeof(Page_ValidationSummaries) == "undefined")
17:         return;
18:     var summary, sums, s;
19:     for (sums = 0; sums < Page_ValidationSummaries.length; sums++) {
20:         summary = Page_ValidationSummaries[sums];
21:         summary.style.display = "none";
22:         if (!Page_IsValid && IsValidationGroupMatch(summary, validationGroup)) {
23:             var i;
24:             if (summary.showsummary != "False") {
25:                 summary.style.display = "";
26:                 if (typeof(summary.displaymode) != "string") {
27:                     summary.displaymode = "BulletList";
28:                 }
29:                 switch (summary.displaymode) {
30:                     case "List":
31:                         headerSep = "
";
32:                         first = "";
33:                         pre = "";
34:                         post = "
";
35:                         end = "";
36:                         break;
37:                     case "BulletList":
38:                     default:
39:                         headerSep = "";
40:                         first = "
    ";
41:                         pre = "
  • ";
  • 42:                         post = "";
    43:                         end = "";
    44:                         break;
    45:                     case "SingleParagraph":
    46:                         headerSep = " ";
    47:                         first = "";
    48:                         pre = "";
    49:                         post = " ";
    50:                         end = "
    ";
    51:                         break;
    52:                 }
    53:                 s = "";
    54:                 if (typeof(summary.headertext) == "string") {
    55:                     s += summary.headertext + headerSep;
    56:                 }
    57:                 s += first;
    58:                 for (i=0; i
    59:                     if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
    60:                         s += pre + Page_Validators[i].errormessage + post;
    61:                     }
    62:                 }
    63:                 s += end;
    64:                 summary.innerHTML = s;
    65:                 window.scrollTo(0,0);
    66:             }
    67:             if (summary.showmessagebox == "True") {
    68:                 s = "";
    69:                 if (typeof(summary.headertext) == "string") {
    70:                     s += summary.headertext + "\r\n";
    71:                 }
    72:                 var lastValIndex = Page_Validators.length - 1;
    73:                 for (i=0; i<=lastValIndex; i++) {
    74:                     if (!Page_Validators[i].isvalid && typeof(Page_Validators[i].errormessage) == "string") {
    75:                         switch (summary.displaymode) {
    76:                             case "List":
    77:                                 s += Page_Validators[i].errormessage;
    78:                                 if (i < lastValIndex) {
    79:                                     s += "\r\n";
    80:                                 }
    81:                                 break;
    82:                             case "BulletList":
    83:                             default:
    84:                                 s += "- " + Page_Validators[i].errormessage;
    85:                                 if (i < lastValIndex) {
    86:                                     s += "\r\n";
    87:                                 }
    88:                                 break;
    89:                             case "SingleParagraph":
    90:                                 s += Page_Validators[i].errormessage + " ";
    91:                                 break;
    92:                         }
    93:                     }
    94:                 }
    95:                 alert(s);
    96:             }
    97:         }
    98:     }
    99: }

    四、ASP.NET是如何实现服务端验证的?

    前面我们花了很大的篇幅介绍了客户端验证,通过介绍我们知道了,客户端验证和错误消息的显示均由Javascript来完成。现在我们来简单看看服务端验证。客户端通过调用__doPostBack实现向服务端的Postback(具体的Postback可以参考我的文章:《》),并进行验证控件的服务端验证,错误消息直接通过Html显示出来。比如下面是一段CustomValidator的验证逻辑。

    1: protected void ctmUserName_ServerValidate(object source, ServerValidateEventArgs args)
    2:     {
    3:         if (this.txtUserName.Text.Trim() != "adm")
    4:         {
    5:             args.IsValid = false;
    6:             return;
    7:         }
    8:         args.IsValid = true;
    9:     }

    如果上面的验证没有通过,最终呈现在客户端浏览器上的将如下图所示,后面是显示验证错误消息的HTML。

     

    作者:蒋金楠
    微信公众账号:大内老A
    微博:
    如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号
    蒋金楠的自媒体将会停用)。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    你可能感兴趣的文章
    MySQL my.cnf参数配置优化详解
    查看>>
    JavaNIO基础02-缓存区基础
    查看>>
    日本开设无人机专业,打造无人机“人才市场”
    查看>>
    190行代码实现mvvm模式
    查看>>
    PXE部署实例
    查看>>
    cobbler初探------实现自动安装centos6.4
    查看>>
    Android Studio 2.0 preview3 BUG
    查看>>
    兼容几乎所有浏览器的透明背景效果
    查看>>
    Go语言4
    查看>>
    jeesite 框架搭建与配置
    查看>>
    Adb移植(一)简单分析
    查看>>
    Linux VNC server的安装及简单配置使用
    查看>>
    阿里宣布开源Weex ,亿级应用匠心打造跨平台移动开发工具
    查看>>
    Android项目——实现时间线程源码
    查看>>
    招商银行信用卡重要通知:消费提醒服务调整,300元以下消费不再逐笔发送短信...
    查看>>
    python全栈_002_Python3基础语法
    查看>>
    C#_delegate - 调用列表
    查看>>
    交换机二层接口access、trunk、hybird三种模式对VLAN的处理过程
    查看>>
    jQuery.extend 函数详解
    查看>>
    [转]Windows的批处理脚本
    查看>>