第三章 验证控件
ASP.NET 2.0/3.5 一共提供了六个验证控件,在仔细了解了这几个验证控件后,才发现以前自己对验证控件有太多的误解,对其了解仅限于表象,对其应用也很不合理。以前我认为:
1. 验证控件和javascript的验证方式是一致的,都是通过js来进行验证
2. 验证控件太丑
3. 验证控件灵活度太差
效果和灵活度不如javascript的验证方式,这些控件最终还是会生成客户端的html和javascript,以上的这些都是对验证控件的误解。
在此章节开始之前,我先阐述并修正我对这些控件的误解。
1. 验证控件和javascript验证
验证控件通过服务器解释,最终呈现到浏览器,我们看到的仍然是一些html/css/js这些浏览器才能识别的语言,默认情况下它既在服务器端执行验证,也在客户端执行验证。服务端的验证是通过表单提交来实现,客户端的验证仍然是通过js来实现,这相当于执行了双重验证。但是js验证仅仅只是通过浏览器解释js脚本来进行验证。
2. 验证控件太丑
验证控件不是太丑,而是我不愿意为验证控件去写css,以前也一直认为验证控件就应该去写属性,但是写属性去调整一个控件,那代码就显得很臃肿,于是就产生了鄙视之的心理。
其实这是我先入为主的思想在作怪,我总是喜欢把客户端和服务器端的东西分开写,也许是Code Behind导致我精神分裂,喜欢把客户端和服务端的东西分的太清。
3. 验证控件灵活度差
验证控件在灵活度上确实不能和javascurip相比,它不能做出像javascript能够表现得动态效果,但是这并不代表它缺乏灵活度,如果足够了解这些控件,合理的结合使用其中的几种控件,也一样能够达到我们预期的效果(如果你正则表达式运用的比较好,只用RegularExpressionValidator控件就能完成所有验证)。
以上这些都是前话,现在开始正题,验证控件的讲述。
六个验证控件:
- RequireFieldValidator——用于要求用户在表单字段中输入必须的值。
- RangeValidator——用于检测一个值是否在确定的最小值和最大值之间。
- CompareValidator——用于比较一个值和另一个值或执行数据类型检查。
- RegularExpressValidator——用于比较一个值和正则表达式。
- CustomValidator——用于执行自定义验证。
- ValidationSummary——用于在页面中显示所有验证错误的摘要。
1.Page.IsValid属性,Display属性,Text属性
每一个验证控件都包含一个IsValid属性,验证正确则返回true,否则返回false。当页面中的所有验证控件的IsValid属性都为true时,Page.IsValid属性才返回true。
Display属性可接收的三个值:Static, Dynamic, None,Display的默认值是Static。
Text属性用于在验证失败时显示错误信息。
1: <%@ Page Language="C#"%>
2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3: <script runat="server">
4: void btnSubmit_Click(Object sender, EventArgs e)
5: {
6: //了解Page.IsValid属性
7: if (Page.IsValid)
8: {
9: lblResult.Text = @"<br />Product:" + this.txtProductName.Text +
10: @"<br />" + "Price:" + this.txtProductPrice.Text +
11: @"<br />" + "Quantity:" + this.txtProductQuantity.Text;
12: }
13:
14: }
15: </script>
16: <html xmlns="http://www.w3.org/1999/xhtml" >
17: <head id="Head1" runat="server">
18: <title>Order Form</title>
19: <style type="text/css">
20: body{
21: font-size: 1em;
22: font-family: "微软雅黑";
23: color: #333333;
24: }
25: </style>
26: </head>
27: <body>
28: <form id="form1" runat="server">
29: <div>
30:
31: <fieldset>
32: <legend>Product Order Form</legend>
33:
34: <asp:Label
35: ID="lblProductName"
36: runat="server"
37: Text="Product Name:"
38: AssociatedControlID="txtProductName"></asp:Label>
39: <asp:TextBox
40: ID="txtProductName"
41: runat="server"></asp:TextBox>
42: <!--Display属性-->
43: <asp:RequiredFieldValidator
44: ID="reqProductName"
45: runat="server"
46: Display="Static"
47: ControlToValidate="txtProductName"
48: Text="(Required)"></asp:RequiredFieldValidator>
49: <br /><br />
50:
51: <asp:Label
52: ID="lblProductPrice"
53: runat="server"
54: Text="Product Price:"
55: AssociatedControlID="txtProductPrice"></asp:Label>
56: <asp:TextBox
57: ID="txtProductPrice"
58: runat="server"></asp:TextBox>
59: <!--Display属性-->
60: <asp:RequiredFieldValidator
61: ID="reqProductPrice"
62: runat="server"
63: ControlToValidate="txtProductPrice"
64: Text="(Required)"
65: Display="Dynamic"></asp:RequiredFieldValidator>
66: <asp:CompareValidator
67: ID="cmpProductPrice"
68: runat="server"
69: ControlToValidate="txtProductPrice"
70: Text="(Invalid Price)"
71: Operator="DataTypeCheck"
72: Type="Currency"></asp:CompareValidator>
73: <br /><br />
74:
75: <asp:Label
76: ID="lblProductQuantity"
77: runat="server"
78: Text="Product Quantity:"
79: AssociatedControlID="txtProductQuantity"></asp:Label>
80: <asp:TextBox
81: ID="txtProductQuantity"
82: runat="server"></asp:TextBox>
83: <!--Display属性-->
84: <asp:RequiredFieldValidator
85: ID="reqProductQuantity"
86: ControlToValidate="txtProductQuantity"
87: Text="(Required)"
88: Display="Dynamic"
89: runat="server"></asp:RequiredFieldValidator>
90: <asp:CompareValidator
91: ID="cmpProductQuantity"
92: runat="server"
93: ControlToValidate="txtProductQuantity"
94: Text="(Invalud Quantity)"
95: Operator="DataTypeCheck"
96: Type="Currency"></asp:CompareValidator>
97: <br /><br />
98:
99: <asp:Button
100: ID="btnSubmit"
101: runat="Server"
102: Text="Submit"
103: OnClick="btnSubmit_Click" />
104:
105: </fieldset>
106:
107:
108: <asp:Label
109: ID="lblResult"
110: runat="server"></asp:Label>
111:
112: </div>
113:
114: </form>
115: </body>
116: </html>
当Display属性值为Static时,验证控件生成的代码如下:
1: <span id="reqProductName" style="color:Red; visibility:hidden">(Required)</span>
当Display属性值为Dynamic时,验证控件生成的代码则是:
1: <span id="reqProductPrice" style="color:Red; display:none">(Required)</span>
虽然visibility属性和display属性都会隐藏文本,但是visiblity即使隐藏了文本,仍然会占用空间,而display属性则不会。
通常情况下,我们都应该设置验证控件的Display属性为Dynamic,当有多个验证控件去验证某个控件时(比如TextBox控件),验证错误时的文本不会被推到右边。
Display属性为None时,验证控件中的Text将不显示,但我们仍然可以通过ValidationSummary控件来进行显示。
事实上,Text属性接收任何HTML字符串,比如Text=”<img src=’error.gif’ />”,以图片的形式来显示错误提示信息。
1: <%@ Page Language="C#"%>
2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3: <script runat="server">
4: </script>
5: <html xmlns="http://www.w3.org/1999/xhtml" >
6: <head id="Head1" runat="server">
7: <title>Validation Image</title>
8: </head>
9: <body>
10: <form id="form1" runat="server">
11: <div>
12: <asp:Label ID="FirstName" runat="server" Text="First Name:" AssociatedControlID="txtFirstName"></asp:Label>
13: <br />
14: <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
15:
16: <!--使用图片进行验证,Text字段接受任何HTML字符串-->
17: <asp:RequiredFieldValidator
18: ID="reqFirstName"
19: runat="server"
20: SetFocusOnError="true"
21: Text="<img src='error.png'/>"
22: ControlToValidate="txtFirstName"></asp:RequiredFieldValidator>
23: <br /><br />
24: <asp:Button ID="submit" runat="server" Text="Submit"/>
25: </div>
26: </form>
27: </body>
28: </html>
2.SetFocusOnError属性,Page.Validators属性
SetFocusOnError属性可以用于强调错误,所有的验证控件都支持这个属性。如果一个验证控件的SetFocusOnError属性为true,当与验证控件相关联的控件验证错误时,会自动关联到这个被验证控件,使它处于焦点状态。
用SetFocusOnError这个属性的强调效果并不明显,如果想真正强调验证错误的控件,可以用Page.Validators属性,这个属性表示页面的验证集合。我们可以利用Page.Validator属性来突出显示每一个验证错误的控件,代码如下:
1: <%@ Page Language="C#"%>
2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3: <script runat="server">
4: void Page_PreRender()
5: {
6: foreach (BaseValidator valControl in Page.Validators)
7: {
8: //通过Page.Validators属性找到验证控件
9: WebControl assControl = (WebControl)Page.FindControl(valControl.ControlToValidate);
10: if (!valControl.IsValid)
11: assControl.BackColor = System.Drawing.Color.Yellow;
12: else
13: assControl.BackColor = System.Drawing.Color.Gray;
14: }
15: }
16: </script>
17: <html xmlns="http://www.w3.org/1999/xhtml" >
18: <head id="Head1" runat="server">
19: <title>Show Page.Validators</title>
20: </head>
21: <body>
22: <form id="form1" runat="server">
23: <div>
24: <asp:Label
25: id="lblFirstName"
26: Text="First Name"
27: AssociatedControlID="txtFirstName"
28: Runat="server" />
29: <br />
30: <asp:TextBox
31: id="txtFirstName"
32: Runat="server" />
33: <!--只有当验证控件的EnableClientScript属性为false属性时,TextBox背景才会变色-->
34: <asp:RequiredFieldValidator
35: id="reqFirstName"
36: ControlToValidate="txtFirstName"
37: Text="(Required)"
38: EnableClientScript="false"
39: Runat="server" />
40:
41: <br /><br />
42:
43: <asp:Label ID="lblLastName" runat="server" Text="Last Name:"></asp:Label>
44: <br />
45: <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
46: <asp:RequiredFieldValidator
47: ID="reqLastName"
48: runat="server"
49: ControlToValidate="txtLastName"
50: Text="(Required)"
51: EnableClientScript="false"></asp:RequiredFieldValidator>
52: <br /><br />
53:
54: <asp:Button
55: id="btnSubmit"
56: Text="Submit"
57: Runat="server" />
58:
59: </div>
60: </form>
61: </body>
62: </html>
3.使用验证组ValidationGroup
我们时常看到一些站点的注册表单和登陆表单在一个页面,而我们又需要对这两个表单进行验证。在验证控件中,有ValidationGroup这样一个属性,可以对验证控件进行分组,给那些验证登录的控件分一组,给用于注册的控件分一组,这样也只需要一个表单。
1: <%@ Page Language="C#"%>
2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3: <script runat="server">
4: /// <summary>
5: /// 登录
6: /// </summary>
7: /// <param name="sender"></param>
8: /// <param name="e"></param>
9: void btnLogin_Click(Object sender, EventArgs e)
10: {
11: if (Page.IsValid)
12: this.lblLoginResult.Text = "Log in Successful!";
13: }
14:
15: /// <summary>
16: /// 注册
17: /// </summary>
18: /// <param name="sender"></param>
19: /// <param name="e"></param>
20: void btnRegister_Click(Object sender, EventArgs e)
21: {
22: if (Page.IsValid)
23: this.lblRegisterResult.Text = "Registration Sucessful!";
24: }
25: </script>
26: <html xmlns="http://www.w3.org/1999/xhtml" >
27: <head id="Head1" runat="server">
28: <title>Show Validation Group</title>
29: <style type="text/css">
30: html
31: {
32: background-color: sliver;
33: font-family:Arial, Helvetica, sans-serif;
34: font-size: 12px;
35: color: #333;
36: }
37: .column
38: {
39: float: left;
40: width: 300px;
41: height: 300px;
42: margin-left: 100px;
43: background: white;
44: border: 1px solid #666;
45: padding: 10px;
46: }
47: input
48: {
49: border: 1px solid #ccc;
50: padding: 3px;
51: }
52: </style>
53: </head>
54: <body>
55: <form id="form1" runat="server">
56: <div class="column">
57: <fieldset>
58: <legend>Login</legend>
59: <p>Please log in to our Website.</p>
60: <asp:Label ID="lblUserName" runat="server" Text="User Name:" AssociatedControlID="txtUserName"></asp:Label>
61: <br />
62: <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox>
63: <!--ValidationGroup="LoginGroup"-->
64: <asp:RequiredFieldValidator
65: ID="reqUserName"
66: runat="server"
67: ControlToValidate="txtUserName"
68: Text="(required)"
69: ValidationGroup="LoginGroup"></asp:RequiredFieldValidator>
70: <br /><br />
71:
72: <asp:Label ID="lblPassword" runat="server" Text="Password:" AssociatedControlID="txtPassword"></asp:Label>
73: <br />
74: <asp:TextBox ID="txtPassword" runat="server" ValidationGroup="LoginGroup"></asp:TextBox>
75: <!--ValidationGroup="LoginGroup"-->
76: <asp:RequiredFieldValidator
77: ID="reqPassword"
78: runat="server"
79: ControlToValidate="txtPassword"
80: Text="(required)"
81: ValidationGroup="LoginGroup"></asp:RequiredFieldValidator>
82: <br /><br />
83: <!--ValidationGroup="LoginGroup"-->
84: <asp:Button ID="btnLogin" runat="server" Text="Login" ValidationGroup="LoginGroup" OnClick="btnLogin_Click"/>
85: </fieldset>
86: <asp:Label ID="lblLoginResult" runat="server"></asp:Label>
87: </div>
88:
89: <div class="column">
90: <fieldset>
91: <legend>Register</legend>
92: <p>
93: If you do not have a User Name, please
94: register at our Website.
95: </p>
96: <asp:Label ID="lblFirstName" runat="server" Text="First Name:" AssociatedControlID="txtFirstName"></asp:Label>
97: <br />
98: <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox>
99: <!--ValidationGroup="RegisterGroup"-->
100: <asp:RequiredFieldValidator
101: ID="reqFirstName"
102: runat="server"
103: ErrorMessage="RequiredFieldValidator"
104: ControlToValidate="txtFirstName"
105: Text="(required)"
106: ValidationGroup="RegisterGroup"></asp:RequiredFieldValidator>
107: <br /><br />
108:
109: <asp:Label ID="lblLastName" runat="server" Text="Last Name:" AssociatedControlID="txtLastName"></asp:Label>
110: <br />
111: <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox>
112: <!--ValidationGroup="RegisterGroup"-->
113: <asp:RequiredFieldValidator
114: ID="reqLastName"
115: runat="server"
116: ErrorMessage="RequiredFieldValidator"
117: ControlToValidate="txtLastName"
118: Text="(required)"
119: ValidationGroup="RegisterGroup"></asp:RequiredFieldValidator>
120: <br /><br />
121: <!--ValidationGroup="RegisterGroup"-->
122: <asp:Button ID="btnRegister" runat="server" Text="Register" ValidationGroup="RegisterGroup" OnClick="btnRegister_Click"/>
123: </fieldset>
124: <asp:Label ID="lblRegisterResult" runat="server"></asp:Label>
125: </div>
126: </form>
127: </body>
128: </html>
上面的代码中,注意两个组,虽然TextBox也有ValidationGroup属性,但是我们不必为TextBox也设置ValidationGroup,只需为验证控件和按钮设置验证组就可以了。在分了验证组以后,两个表单的行为互不干涉。
4. 禁用验证
所有的按钮控件Button, ImageButton, LinkButton都有一个CauseValidation属性,如果设置这个按钮的CauseValidation属性为false,那么当点击这个按钮时将绕过页面中的所有验证。
下面的代码中,采用一个取消按钮,当点击它时,不对表单进行验证,而是重定向到Default页面
1: <%@ Page Language="C#"%>
2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3: <script runat="server">
4: void btnCancel_Click(Object sender, EventArgs e)
5: {
6: Response.Redirect("~/Default.aspx");
7: }
8: </script>
9: