本篇要讲述的知识点如下:
数据验证介绍
纯客户端脚本验证
asp.net 验证控件概述
RequiredFieldValidator 控件
CompareValidator 控件
RangeValidator 控件
正则表达式
RegularExpressionValidator 控件
CustomValidator 控件
ValidationSummary 控件
分组校验技术

数据验证介绍
在我们的开发中要提高网站的健壮性,为了做到这些笔者曾经在企业培训时候提到了两个原则:
第一条原则:就是尽量减少让用户输入的机会,比如数据的录入时间我们可以设置该条记录的为数据库的当前时间,这个可以在创建或者设计表的时候实现。下面就是一个例子:

  1. 1.    create table ActionLog ( 
  2. 2.       LogID                bigint               identity(1,1), 
  3. 3.       UserID               int                  not null
  4. 4.       UserIP               varchar(15)          not null
  5. 5.       ActionDate           datetime             null default getdate(), 
  6. 6.       ActionDescription    nvarchar(800)        not null
  7. 7.       ActionStatus         tinyint              not null
  8. 8.       WebSiteID            int                  not null
  9. 9.       constraint PK_ACTIONLOG primary key (LogID) 
  10. 10.    ) 
  11. 11.    Go

上面中的ActionDate 字段就是设置成自动获取数据库服务器当前时间,这样在插入记录的时候无需在这个字段插入值。如果这个值让用户填写一来可能用户不能按照我们要求的格式填写,二来即使按照我们的要求填写也可能用户不会填写当前时间,如果采用上面的办法就能有效避免这个问题。
第二条原则:就是不要过分相信用户一定会按照我们的要求规规矩矩去做。最终使用我们的软件产品的用户大都计算机水平不高(如果水平高可能就会自己开发了),所以他们可能不太懂得什么格式和要求之类的,这就经常需要对用户填写的数据进行检查。如果我们对用户提交的数据经过充分检查,那么就能有效提高程序的健壮性,这样也能从某些途径堵住了黑客入侵我们系统的路子。


对数据的检查按时机来分可以分为客户端检查和服务器端检查。


在客户端检查是指通过客户端脚本(如javascript 脚本或者vbscript 脚本)来进行检查,利用客户端脚本检查的好处是减小网络流量、减轻服务器压力和反映迅速。因为客户端脚本是在客户端运行,我们可以定义好检验规则,在客户端就可以完成检验,一旦不能通过验证客户端马上就能得到提示,而不用将整个表单提交到服务器(笔者早些年曾经就有这样的经历:网速28.8K 的情况下提交一个注册表单,数分钟后得到服务器的反馈说是用户名不符合要求,当时差点吐血),用户体验非常好。客户端验证也有一些缺点:因为我们的验证规则完全定义在客户端脚本中,不怀好意的窥探者可以从这些客户端代码找出我们脚本的漏洞或者某些跳过脚本验证的方法,从而造成网站的健壮性出现问题,这就对客户端代码的客户端脚本编程能力提出了挑战。另外客户端验证可能会使我们写得非常优秀的代码在短短几天流传整个网络,不能进行版权控制。
在服务器端检查是指将表单提交到服务器后在服务器上用服务器端代码进行验证(如用C# 或者VB.NET 等),服务器端验证的优点是我们的验证规则对用户来说是一个黑匣子,比较难找出我们验证代码的漏洞,并且服务器端验证的代码编写起来相对客户端脚本要容易得多,但是服务器端验证也有缺点:那就是大量的复杂验证会降低服务器的性能。
因此一般验证办法都是上面两种样式结合,利用客户端验证建立验证的第一道关卡,这个关卡将大量无意中填写的不符合要求的数据阻止在客户端,然后在服务器端建立第二道关卡,将那些利用了我们的客户端脚本漏洞的数据阻止在保存之前。

客户端脚本验证
下面是一个利用客户端脚本在客户端进行验证的例子。我们对Button 服务器控件的OnClientClick 加上一个客户端验证方法,只有当这个客户端方法返回true 的时候表单才会向服务器提交,如果用户填写的数据不符合要求就返回false 值。
下面是前台代码(后台没有编写任何代码):

  1. 1.    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ClientValidate.aspx.cs" Inherits="ClientValidate" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  6. 6.    <head runat="server"
  7. 7.        <title>纯客户端脚本验证的例子</title> 
  8. 8.        <script language="javascript" type="text/javascript"
  9. 9.            //当这个方法返回false的情况下就不会向服务器提交数据 
  10. 10.            function checkForm() 
  11. 11.            { 
  12. 12.                //如果没有填写任何数据 
  13. 13.                if(document.form1.txtUserName.value==""
  14. 14.                { 
  15. 15.                    alert("用户名不能为空!"); 
  16. 16.                    return false
  17. 17.                } 
  18. 18.                var length=document.form1.txtUserName.value.length; 
  19. 19.                //如果填写内容长度不在6到10字符之间 
  20. 20.                if(length<6||length>10
  21. 21.                { 
  22. 22.                    alert("用户名必须是6到10个字符!"); 
  23. 23.                    return false
  24. 24.                } 
  25. 25.                else 
  26. 26.                { 
  27. 27.                    return true
  28. 28.                } 
  29. 29.            } 
  30. 30.        </script> 
  31. 31.    </head> 
  32. 32.    <body> 
  33. 33.        <form id="form1" runat="server"
  34. 34.        <div> 
  35. 35.            <table border="0"
  36. 36.            <tr><td>用户名</td><td><asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td></tr> 
  37. 37.            <tr><td><asp:Button ID="btnOK" runat="server" Text="提交" OnClientClick="javascript:return checkForm();" OnClick="btnOK_Click" /></td><td><input type="reset" value="清空" /></td></tr> 
  38. 38.            </table> 
  39. 39.             
  40. 40.            </div> 
  41. 41.        </form> 
  42. 42.    </body> 
  43. 43.    </html>

运行效果如下:
 
如果用户没有填写任何数据就提交表单会得到如下提示:
 
如果我们填写的字符个数不是6 到10 个之间提交表单会看到如下效果:
 
通过上面的例子展示了如何在asp.net 中如何利用客户端脚本对表单进行验证,经过上面的大家也能感觉得到用客户端脚本对表单进行验证的编码特点:可以灵活控制验证方法,但是编写客户端脚本比较麻烦,调试起来也不太容易,在目前还没有一款比较好的javascript 脚本编写和调试的软件。为了提高开发asp.net 网站的速度,微软提供了一套asp.net 的验证控件。

asp.net 验证控件概述
所有的asp.net 验证控件都直接或者间接派生自BaseValidator 这个抽象类,BaseValidator 类定义了验证控件的一些共有属性和方法。验证控件用于验证与其关联的输入控件的值,当用户的输入不能通过验证时,将会显示预定义的错误提示信息。验证控件的位置并没有规定,可以在页面的任意位置放置验证控件,但是一般为了直观起见,尽量将验证控件靠近要验证的控件的位置。asp.net 验证控件可以对以下类型的asp.net 控件的值进行验证:

控件名

要验证的属性

备注

DropDownList

SelectedValue

验证选中项的值

FileUpload

FileName

验证要上传的文件名

ListBox

SelectedItem.Value

验证选中的第一项的值

RadioButtonList

SelectedItem.Value

验证选中项的值

TextBox

Text

验证文本框的值

HtmlInputFile

Value

验证HTML 服务器上传控件中的文件名

HtmlInputPassword

Value 

验证HTML 服务器文本控件的值

HtmlInputText 

Value

验证HTML 服务器文本控件的值

HtmlSelect

Value

验证HTML 服务器下拉控件选中的值

HtmlTextArea

Value

验证HTML 服务器多行文本控件的值

从上表中我们可以看出验证控件验证的控件类型只能是asp.net 服务器控件和HTML 服务器控件,而不能验证普通HTML 控件,如果要普通HTML 控件进行验证,只能像笔者在上一个例子中演示的那样自己编写客户端脚本代码进行验证。
在默认情况下,asp.net 服务器控件将首先在客户端进行验证,然后再发送到服务器端进行验证,当然也可以设置它的EnableClientScript 属性来指定是否需要在客户端进行验证。BaseValidator 类有如下常见属性:

属性名

说明

ControlToValidate

待验证的控件的ID

Display

错误信息的显示方式,有None 、Static 和Dynamic ,默认为Static

EnableClientScript

是否启用客户端验证

Enabled

是否启用验证控件

ErrorMessage

验证失败时显示的信息

IsValid

关联的控件是否通过验证

SetFocusOnError

当验证失败时是否将焦点移动到关联的控件上

Text

验证失败时在验证控件中要显示的信息

ValidationGroup

验证控件所在的分组名

对上面几个属性做一点说明:
(1 )Display 属性是决定如何显示错误消息的,默认是Static ,即始终为错误信息分配显示空间,Dynamic 方式是只在需要的时候才为错误信息分配显示空间,而None 方式是将错误信息集中到ValidationSummary 控件中显示。
(2 )ErrorMessage 属性是待验证控件不能通过验证的时候在ValidationSummary 控件中显示要显示的信息,Text 属性是待验证控件不能通过验证是在验证控件中显示的信息,如果只设置了ErrorMessage 属性而没有设置Text 属性并且Display 方式不为None 时将会显示ErrorMessage 属性的值。
(3 )ControlToValidate 是必须指定的,否则在运行的时候将会报错。

RequiredFieldValidator 控件
RequiredFieldValidator 控件也被称之为必填验证控件,顾名思义,也就是与RequiredFieldValidator 控件关联的控件的值在默认设置下必须填写。笔者在这里用了个限定词“ 在默认设置下” ,是因为RequiredFieldValidator 控件除了BaseValidator 中定义的属性之外,还有一个比较重要的属性:InitialValue 。默认情况下这个属性的值是String.Empty ,如果控件的值与它的默认值一致就不能通过验证,即如果关联的控件没有填写的话就不能通过验证,在验证DropDownList 控件的时候我们也可以使用RequiredFieldValidator 控件,不过需要设置RequiredFieldValidator 控件的InitialValue 属性。
下面我们通过一个例子来演示RequiredFieldValidator 控件如何验证TextBox 控件和DropDownList 控件。在程序中我们给DropDownList 控件添加了一个默认选项“ 请选择” ,一旦用户没有改变DropDownList 控件的选中值就不能通过验证。
在设置验证控件的关联控件时,验证控件会自动找出当前页面中哪些控件是可以进行验证的,如下图:

注意: 在上图中控件ID 不是TextBox1 或者DropDownList 这种默认形式,是因为我更改了其默认ID 。在实际开发中我一般会更改控件的默认ID ,用一个比较直观的ID ,这样便于我们在代码中操作。我对服务器控件的ID 命名一般遵循控件类型前缀加控件用户的办法,下面举例说明:

控件类型

前缀

举例

TextBox

txt

txtUserName

Label

lb

lbServerTime

DropDownList

ddl

ddlState

Literal

l

lTitle

Button

btn

btnOK

RadioButton

rb

rbMale

CheckBox

cb

cbApply

这样的做法比整个页面一堆Button1 、Button2 及TextBox1 、TextBox2 强得多,基本上能做到望文知义。

因为只是演示验证控件的验证效果,所以没有什么后台代码,采用了单页模式。下面是实例代码:

  1. 1.    <%@ Page Language="C#" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <script runat="server"
  6. 6.    
  7. 7.    </script> 
  8. 8.    
  9. 9.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  10. 10.    <head runat="server"
  11. 11.        <title>RequiredFieldValidator控件用法的例子</title> 
  12. 12.    </head> 
  13. 13.    <body> 
  14. 14.        <form id="form1" runat="server"
  15. 15.        <div> 
  16. 16.            <table border="1" width="400"
  17. 17.        <tr><td>用户名</td><td> 
  18. 18.            <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox> 
  19. 19.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtUserName" 
  20. 20.                ErrorMessage="用户名必须填写"></asp:RequiredFieldValidator></td></tr> 
  21. 21.        <tr><td>省份</td><td> 
  22. 22.            <asp:DropDownList ID="ddlState" runat="server"
  23. 23.                <asp:ListItem Selected="True">请选择</asp:ListItem> 
  24. 24.                <asp:ListItem Value="1">湖北</asp:ListItem> 
  25. 25.                <asp:ListItem Value="2">湖南</asp:ListItem> 
  26. 26.                <asp:ListItem Value="3">山东</asp:ListItem> 
  27. 27.                <asp:ListItem Value="4">山西</asp:ListItem> 
  28. 28.                <asp:ListItem Value="5">河南</asp:ListItem> 
  29. 29.                <asp:ListItem Value="6">河北</asp:ListItem> 
  30. 30.            </asp:DropDownList> 
  31. 31.            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="ddlState" 
  32. 32.                ErrorMessage="请选择省或者直辖市" InitialValue="请选择"></asp:RequiredFieldValidator></td></tr> 
  33. 33.        <tr><td> 
  34. 34.            <asp:Button ID="btnOK" runat="server" Text="提交" /> 
  35. 35.        </td><td> 
  36. 36.              
  37. 37.            <input id="Reset1" type="reset" value="reset" /></td></tr> 
  38. 38.        </table> 
  39. 39.            </div> 
  40. 40.        </form> 
  41. 41.    </body> 
  42. 42.    </html>

下面是运行效果:



当我们直接点击“ 提交” 之后的效果:
 
一旦我们填写了用户名,并且选择一个省份而不是让“ 请选择” 处于选中状态,那么这个表单就能提交到服务器进行处理了。在这个例子里我们没有写一行客户端脚本代码。

CompareValidator 控件
CompareValidator 控件也被称之为比较验证控件,它是用来验证两个控件的值或者控件与某个值之间的关系,除了在BaseValidator 中定义的属性之外,CompareValidator 控件还定义了如下属性:

属性名

说明

ControlToCompare

要与所验证的输入控件进行比较的输入控件的ID

Operator

要执行的比较操作

Type

对控件的值按照哪种方式进行比较,默认String

ValueToCompare

设置要与所验证的控件的值进行比较的值

说明:因为在输入控件中可以输入货币、浮点数、整数及字符串等,所以需要设置控件的值按照什么类型的值进行验证,可以进行验证的类型有如下:

类型

说明

Currency

按货币类型比较,小数点后最多两位数字

Date

按日期类型比较(不带时分秒)

Double

按浮点数类型比较

Integer 

按整数类型比较

String

按字符串类型比较

在进行验证的时候还可以指定两个值之间满足什么关系不能通过验证,这个关系可以通过设置Operator 属性来指示,分别有< (LessThan )、<= (LessThanEqual )、!= (NotEqual )、= (Equal )、> (GreaterThan )及>= (GreaterThanEqual )。
另外有时候我们可能不是将两个控件的值进行比较,而是将所验证的控件的值与某个指定的值进行比较,那么可以不设置ControlToCompare 属性的值而设置ValueToCompare 属性的值,验证的时候将用ValueToCompare 属性的值与所验证的控件的值按照Type 属性指定的类型和Operator 属性定义的比较操作来进行验证。
注意:请不要同时设置ControlToCompare 属性和ValueToCompare 属性,如果同时指定了这两个属性,则ValueToCompare 属性优先。
CompareValidator 控件用得比较多的场合就是用于确保用户在注册时两次输入的密码一致,还有在某些场合下有一定先后顺序的日期数据,比如某个事件的开始日期和结束日期。
经常看香港警匪片的朋友一定会对警察抓捕嫌疑犯时经常说的那句“ 你有权保持沉默,但是你所说的将来会成为呈堂证供” 不陌生, 在asp.net 中除了RequiredFieldValidator 控件之外,CompareValidator 控件、RangeValidator 控件和RegularExpressionValidator 控件对待所验证的控件也是持这种态度:所验证的控件如果没有任何输入也是能通过验证的,但是如果输入的数据不符合验证规则就不能通过验证! 要是要求用户必须输入并且还要符合一定规则,上述的控件就需要结合RequiredFieldValidator 控件共同验证。
在下面的例子中要用户填写一个旅游申请,要填写的数据有旅游出发时间、旅游人数、旅游经费及旅游结束时间。根据业务规则,在这个表单中有如下要求:
(1 )出发时间一定早于结束时间。
(2 )旅游人数一定要大于0 (一个人都不参加这个旅游就没有意义了)。
(3 )旅游经费可以不填写(难以估算),但一旦填写就必须填写大于0.00 的金额。
在这里所有的验证都是用CompareValidator 控件结合RequiredFieldValidator 控件来进行验证,RequiredFieldValidator 控件验证所验证的控件是否填写了数据,CompareValidator 控件负责进行比较验证,代码如下:

  1. 1.    <%@ Page Language="C#" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <script runat="server"
  6. 6.    
  7. 7.    </script> 
  8. 8.    
  9. 9.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  10. 10.    <head runat="server"
  11. 11.        <title>CompareValidator灵活使用的例子</title> 
  12. 12.    </head> 
  13. 13.    <body> 
  14. 14.        <form id="form1" runat="server"
  15. 15.        <div> 
  16. 16.        <table border="1" width="600"
  17. 17.        <tr><td colspan="2" align="center">旅游活动申请表</td></tr> 
  18. 18.        <tr><td> 
  19. 19.            开始时间</td><td> 
  20. 20.            <asp:TextBox ID="txtStartDate" runat="server"></asp:TextBox> 
  21. 21.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtStartDate" 
  22. 22.                ErrorMessage="用户名必须填写"></asp:RequiredFieldValidator> 
  23. 23.                <asp:CompareValidator ID="CompareValidator1" runat="server" ErrorMessage="开始日期必须早于结束日期" ControlToCompare="txtStartDate" ControlToValidate="txtEndDate" Operator="GreaterThanEqual" Type="Date"></asp:CompareValidator></td></tr> 
  24. 24.        <tr><td> 
  25. 25.            结束时间</td><td> 
  26. 26.            <asp:TextBox ID="txtEndDate" runat="server"></asp:TextBox> 
  27. 27.            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtEndDate" 
  28. 28.                ErrorMessage="请填写结束时间"></asp:RequiredFieldValidator> 
  29. 29.                </td></tr> 
  30. 30.        <tr><td> 
  31. 31.           参加人数</td><td> 
  32. 32.            <asp:TextBox ID="txtNumber" runat="server"></asp:TextBox> 
  33. 33.               <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="txtNumber" 
  34. 34.                   ErrorMessage="必须填写人数"></asp:RequiredFieldValidator> 
  35. 35.               <asp:CompareValidator ID="CompareValidator2" runat="server" ControlToValidate="txtNumber" 
  36. 36.                   ErrorMessage="人数必须大于0" Operator="GreaterThan" Type="Integer" ValueToCompare="0"></asp:CompareValidator></td></tr> 
  37. 37.            <tr><td> 
  38. 38.                经费预算</td><td> 
  39. 39.                <asp:TextBox ID="txtMoney" runat="server"></asp:TextBox> 
  40. 40.                    <asp:CompareValidator ID="CompareValidator3" runat="server" ControlToValidate="txtMoney" 
  41. 41.                        ErrorMessage="经费必须是大于0的数字" Type="Currency" ValueToCompare="0"  Operator="GreaterThan"></asp:CompareValidator></td></tr> 
  42. 42.            <tr><td> 
  43. 43.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  44. 44.        </td><td> 
  45. 45.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  46. 46.        </table> 
  47. 47.        </div> 
  48. 48.        </form> 
  49. 49.    </body> 
  50. 50.    </html>

下面不填写任何信息提交表单的效果:
 
从上图我们可以得出一个结论:因为经费预算只使用了CompareValidator 控件,所以如果用户不填写任何信息是能够通过验证的。
现在我们填写表单,这里故意将结束时间设置得比开始时间早,并且在参加人数中填写了一个“q” ,下面是提交表单的效果:
 
从上面的效果我们可以得出下面的结论:
(1 )如果填写数据不能按照期望的数据类型进行转换时是不能通过验证的,因为我们期望用户在参加人数一栏填写大于0 的数字,用户填写了英文字母所以不能通过验证。同理,如果用户在经费预算一栏中填写了不能转换成货币的数字(即小数点后最多两位数字的浮点数)、在开始时间或者结束时间填写了不能转换成日期的数据都是不能通过验证的。
(2 )验证控件的Display 属性默认为Static ,在这种情况下即使所验证的控件通过了验证,但是页面仍然为其分配了显示控件,比如用于验证开始时间、结束时间和参加人数的RequiredFieldValidator 控件,虽然满足了必须填写的要求,可是因为它们的属性都是static 的,所以当不能通过CompareValidator 控件的验证时,CompareValidator 控件的错误提示信息仍然与文本框保持了一段距离。
现在我们把页面上所有验证的Display 的属性设置为Dynamic ,也就是仅在必要的时候页面才为其分配显示空间,因为Display 属性是所有验证控件所共有的属性,所以我们可以按住Ctrl 键的同时用鼠标选取所有的验证控件,然后集中设置所有控件的Display 属性,如下图:
 
我们重新运行页面,填写和上次一样的信息,然后提交表单,这次的错误提示信息与文本框之间的距离就没有刚才那么明显了,效果如下:
 
这是如果我们将开始时间和结束时间的值互换,并且在参加人数一栏填写大于0 的整数时就能提交表单到服务器进行处理。
提示:其实所有的错误信息都是通过<span></span> 方式输出的,当验证控件的Display 属性为Static 时输出的span 格式是“<span style="color:Red; visibility:hidden;"></span>” 这样的形式,当Display 属性为Dynamic 时输出的span 格式是“<span style="color:Red; display:none;"></span>” 这样的形式。

RangeValidator 控件
RangeValidator 控件也称之为范围验证控件,也就是只有当用户填写的非空数据不在指定的范围之间时就不能通过验证。除了具有BaseValidator 所有的属性之外,它还具有如下常见属性:

属性名

说明

MaximumValue

允许的最大值

MinimumValue

允许的最小值

Operator

要执行的比较操作

Type

对控件的值按照哪种方式进行比较,默认String

下面是一个RangeValidator 控件的例子。比如在实际中开发一个婚恋网站,里面有一栏是填写用户生日的,有一栏是用户填写生日信息的,因为婚恋网站是针对成年人的,所以我们可以根据用户填写的生日来确保用户填写表单时年龄在18 岁至100 岁之间(不要告诉我超过了100 岁的人还搞婚恋,I 服了U ),如果未超过18 岁则不能注册,这个时间是根据用户填写表单的时间进行判断的,所以我们没有直接给RangeValidator 控件赋最大值和最小值,而是在页面运行获取当前服务器时间,用户所能填写的生日必须当前日期之前100 年至18 年之间,这样就保证了用户在注册时年龄在18 岁至100 之间。下面是代码:

  1. 1.    <%@ Page Language="C#" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <script runat="server"
  6. 6.    
  7. 7.        protected void Page_Load(object sender, EventArgs e) 
  8. 8.        { 
  9. 9.            //注意因为是需要根据填写表单的日期动态判断 
  10. 10.            //所以在这里动态给RangeValidator赋最大值和最小值 
  11. 11.            DateTime minimumValue=DateTime.Now.AddYears(-100); 
  12. 12.            DateTime maximumValue = DateTime.Now.AddYears(-18); 
  13. 13.            RangeValidator1.MinimumValue = minimumValue.ToString("yyyy-MM-dd"); 
  14. 14.            RangeValidator1.MaximumValue =maximumValue.ToString("yyyy-MM-dd") ; 
  15. 15.        } 
  16. 16.    </script> 
  17. 17.    
  18. 18.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  19. 19.    <head runat="server"
  20. 20.        <title>RangeValidator控件验证的例子</title> 
  21. 21.    </head> 
  22. 22.    <body> 
  23. 23.        <form id="form1" runat="server"
  24. 24.        <div> 
  25. 25.        <table border="1" width="600"
  26. 26.        <tr><td colspan="2" align="center"
  27. 27.            周公婚恋交友网</td></tr> 
  28. 28.        <tr><td> 
  29. 29.            生日</td><td> 
  30. 30.            <asp:TextBox ID="txtBirthday" runat="server"></asp:TextBox> 
  31. 31.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtBirthday" 
  32. 32.                ErrorMessage="生日必须填写" Display="Dynamic"></asp:RequiredFieldValidator> 
  33. 33.            <asp:RangeValidator ID="RangeValidator1" runat="server" Display="Dynamic" ErrorMessage="你的年龄不能注册" 
  34. 34.                MaximumValue="" MinimumValue="" Type="Date" ControlToValidate="txtBirthday"></asp:RangeValidator></td></tr> 
  35. 35.            <tr><td> 
  36. 36.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  37. 37.        </td><td> 
  38. 38.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  39. 39.        </table> 
  40. 40.        </div> 
  41. 41.        </form> 
  42. 42.    </body> 
  43. 43.    </html>

下面是运行结果:

正则表达式
正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正则表达式的全面模式匹配表示法使您可以快速分析大量文本以找到特定的字符模式;提取、编辑、替换或删除文本子字符串;或将提取的字符串添加到集合以生成报告。对于处理字符串(例如HTML 处理、日志文件分析和 HTTP 标头分析)的许多应用程序而言,正则表达式是不可缺少的工具。正则表达式是一个非常有用的技术,有人曾称之为能让程序员不至于丢掉饭碗的十大技术之一,可见它的重要性。完全详细讲述正则表达式的用法可能需要厚厚一本书(我也曾经见过一本厚厚的讲述正则表达式的英文书),但是在本系列课程里限于篇幅只能做一个简单的介绍,有兴趣的朋友可以参考其它书籍。
熟悉DOS 或者命令行的朋友或许已经用过类似的功能,比如我们要查找某个文件夹下所有的低于Word2007 版本的Word 文件(因为低于Word2007 版本的Word 文件的文件后缀是.doc ,而Word2007 版本的Word 文件的文件后缀是.docx ),我们可以在命令行下执行这个命名:dir *doc ,下面是在笔者的电脑上执行的结果:



在“dir *doc” 中,* 就是表示任何字符的意思。
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。元字符使正则表达式具有处理能力。下面是一些常见的元字符:

元字符

说明

.

匹配除 \n 以外的任何字符。

[abcde]

匹配abcde 之中的任意一个字符

[a-h]

匹配a 到h 之间的任意一个字符

[^fgh]

不与fgh 之中的任意一个字符匹配

\w

匹配大小写英文字符及数字0 到9 之间的任意一个,相当于[a-zA-Z0-9]

\W

不匹配大小写英文字符及数字0 到9 之间的任意一个,相当于[^a-zA-Z0-9]

\s

匹配任何空白字符,相当于[ \f\n\r\t\v]

\S

匹配任何非空白字符,相当于[^\s]

\d

匹配任何0 到9 之间的单个数字,相当于[0-9]

\D

不匹配任何0 到9 之间的单个数字,相当于[^0-9]

上面的元字符都是针对单个字符匹配的,要想同时匹配多个字符的话,还需要借助限定符。下面是一些常见的限定符( 下表中n 和m 都是表示整数) :

限定浮

说明

*

匹配0 到多个元字符,相当于{0,}

?

匹配0 到1 个元字符,相当于{0,1}

{n}

匹配n 个元字符

{n,}

匹配至少n 个元字符

{n,m}

匹配n 到m 个元字符

+

匹配至少1 个元字符,相当于{1,}

^

字符串必须以指定的字符开始

$

字符串必须以指定的字符结束

说明:
(1 )由于在正则表达式中“\” 、“?” 、“*” 等字符已经具有一定特殊意义,如果需要用它们的原始意义,则应该对它进行转义,例如希望在字符串中至少有一个“\” ,那么正则表达式应该这么写:\\+ 。
(2 )可以将多个元字符或者原义文本字符用括号括起来形成一个新的元字符,比如^(13)[0-9]\d{8}$ 表示任意以13 开头的手机号码。
(3 )另外对于中文字符的匹配是采用其对应的Unicode 编码来匹配的,对于单个Unicode 字符,如\u4e00 表示汉字“ 一” , \u9fa5 表示汉字“ 龥” ,在Unicode 编码中这分别是所能表示的汉字的第一个和最后一个的Unicode 编码,在Unicode 编码中能表示20901 个汉字。
不要认为我记性好,我是从来不记这个的,每次用的时候我都会写一个小程序,查看其运行结果就行了。下面是我这个程序的代码:

  1. 1.    using System; 
  2. 2.    using System.IO; 
  3. 3.    
  4. 4.    public class UnicodeDemo 
  5. 5.    { 
  6. 6.        public static void Main() 
  7. 7.        { 
  8. 8.            using (StreamWriter writer = new StreamWriter(new FileStream("Unicode.txt", FileMode.Create))) 
  9. 9.            { 
  10. 10.                int value = 0
  11. 11.                //从字符的所能表示的最小值到最大值进行遍历 
  12. 12.                for (char c = char.MinValue; c <= char.MaxValue; c++) 
  13. 13.                { 
  14. 14.                    value = (int)c; 
  15. 15.                    //按照 数值=Unicode值=字符 的方式写入到Unicode.txt文件中 
  16. 16.                    //19968=\u4e00=一 即第一个汉字 
  17. 17.                    //40869=\u9fa5=龥 即最后一个汉字 
  18. 18.                    writer.WriteLine("{0}=\\u{1}={2}", value,value.ToString("x"), c); 
  19. 19.                } 
  20. 20.            } 
  21. 21.        } 
  22. 22.    }

将代码编译生成Windows 下的控制台程序,运行会在上面会抛出异常,因为有些字符在笔者所使用的编码范围中无法表示,不过这不影响我们查看汉字的范围。最后生成的文件内容如下:
 
因为汉族的人名最少两个汉字(比如张三),最多四个汉字(比如东方不败),所以匹配汉族的人名可以用这样的形式:[\u4e00-\u9fa5]{2,4} 。

RegularExpressionValidator 控件
RegularExpressionValidator 控件就是利用正则表达式来验证其它控件的值的控件。除了具有BaseValidator 所有的属性之外,它还具有一个常见属性:ValidationExpression 。这个属性就是用来设置用于匹配所要验证控件的值的正则表达式。
RegularExpressionValidator 控件提供了一个正则表达式编辑器,内置了一些常见的正则表达式,当我们在属性窗口设置RegularExpressionValidator 控件时会看到如下效果:
 
点击ValidationExpression 一栏右边的省略号会出现如下界面:
 
如果时一些常用的正则验证,可以使用使用提供标准表达式。
下面是RegularExpressionValidator 控件用法的例子:

  1. 1.    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="RegularExpressionValidatorDemo.aspx.cs" Inherits="RegularExpressionValidatorDemo" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  6. 6.    <head runat="server"
  7. 7.        <title>RegularExpressionValidator控件的例子</title> 
  8. 8.    </head> 
  9. 9.    <body> 
  10. 10.        <form id="form1" runat="server"
  11. 11.        <div> 
  12. 12.        <table border="1" width="600"
  13. 13.        <tr><td colspan="2" align="center"
  14. 14.            周公婚恋交友网</td></tr> 
  15. 15.        <tr><td> 
  16. 16.            真实姓名</td><td> 
  17. 17.            <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox> 
  18. 18.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtUserName" 
  19. 19.                ErrorMessage="姓名必须填写" Display="Dynamic"></asp:RequiredFieldValidator> 
  20. 20.                <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="姓名是2到4个汉字" ControlToValidate="txtUserName" Display="Dynamic" ValidationExpression="[\u4e00-\u9fa5]{2,4}"></asp:RegularExpressionValidator></td></tr> 
  21. 21.            <tr><td> 
  22. 22.            手机号</td><td> 
  23. 23.            <asp:TextBox ID="txtMobile" runat="server"></asp:TextBox> 
  24. 24.            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtMobile" 
  25. 25.                ErrorMessage="姓名必须填写" Display="Dynamic"></asp:RequiredFieldValidator> 
  26. 26.                <asp:RegularExpressionValidator ID="RegularExpressionValidator2" runat="server" ControlToValidate="txtMobile" 
  27. 27.                    ErrorMessage="不正确的手机号" ValidationExpression="((13[0-9])|(15[89]))\d{8}"></asp:RegularExpressionValidator></td></tr> 
  28. 28.            <tr><td> 
  29. 29.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  30. 30.        </td><td> 
  31. 31.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  32. 32.        </table> 
  33. 33.        </div> 
  34. 34.        </form> 
  35. 35.    </body> 
  36. 36.    </html>

在例子中要求真实姓名必须是2 到4 个汉字,手机号必须是13 开头或者是158 、159 开头的并且总长度是11 位数字。以下是运行效果:
 

CustomValidator 控件
CustomValidator 控件也成为自定义验证控件,通过RequiredFieldValidator 控件结合CompareValidator 控件、RangeValidator 控件或RegularExpressionValidator 控件之中的一个或多个就能满足asp.net 开发中的90% 以上的验证要求,但是有一些特殊的验证用上述控件组合无法达到验证要求,比如要求用户填写一个奇数。为了满足一些特殊的验证要求,在asp.net 中还有一个CustomValidator 控件,在这个控件中可以自己写验证规则。
CustomValidator 类是BaseValidator 抽象类,所以CustomValidator 控件拥有BaseValidator 中定义的属性,除此之外,CustomValidator 控件还有以下常见属性:

属性名

说明

ClientValidationFunction

用于在客户端执行验证的客户端函数名

ValidateEmptyText

是否验证空文本,即当所验证控件值为空时时候执行客户端验证

CustomValidator 控件用于在客户端验证的函数有两个参数,第一个是表示被验证的控件,第二个表示事件数据。第二个参数有两个属性:IsValid 用于表示被验证控件是否通过验证,Value 属性表示被验证的控件的值。下面就是一个客户端验证函数的例子:

  1. 1.    <script language="javascript" type="text/javascript"
  2. 2.            //obj表示被验证的控件 
  3. 3.            //args表示事件数据,args有两个属性 
  4. 4.            //IsValid指示控件是否通过验证 
  5. 5.            //Value表示被验证的控件的值 
  6. 6.            function CheckEven(obj,args) 
  7. 7.            { 
  8. 8.                var numberPattern=/\d+/; 
  9. 9.                //由于控件的ValidateEmptyText设置为true 
  10. 10.                //所以当控件没有值时进行客户端验证 
  11. 11.                if(!numberPattern.test(args.Value))//用javascript进行客户端正则验证 
  12. 12.                { 
  13. 13.                    args.IsValid=false;//表示未通过验证,出现错误提示 
  14. 14.                } 
  15. 15.                else if(args.Value%2==0
  16. 16.                { 
  17. 17.                    args.IsValid=true;//表示通过验证,不出现错误提示 
  18. 18.                } 
  19. 19.                else 
  20. 20.                { 
  21. 21.                    args.IsValid=false;//表示未通过验证,出现错误提示 
  22. 22.                } 
  23. 23.            } 
  24. 24.    </script>

除了客户端验证之外,在CustomValidator 控件中还能自己写服务器端写验证方法,它有一个OnServerValidate 事件,同它的客户端处理函数一样,处理这个事件的委托也需要两个参数,第一个是表示被验证的控件,第二个表示事件数据。第二个参数有两个属性:IsValid 用于表示被验证控件是否通过验证,Value 属性表示被验证的控件的值。它服务器端验证方法设置界面如下:

下面我们用一个例子来说明CustomValidator 控件的用法,在这里例子里用户被要求输入两个数,一个必须是2 的倍数,一个必须是3 的倍数。用CustomValidator 控件就能很轻松完成这个功能。
下面是前台代码:

  1. 1.    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="CustomValidatorDemo.aspx.cs" Inherits="CustomValidatorDemo" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  6. 6.    <head runat="server"
  7. 7.        <title>CustomValidator验证控件用法的例子</title> 
  8. 8.        <script language="javascript" type="text/javascript"
  9. 9.            //obj表示被验证的控件 
  10. 10.            //args表示事件数据,args有两个属性 
  11. 11.            //IsValid指示控件是否通过验证 
  12. 12.            //Value表示被验证的控件的值 
  13. 13.            function CheckEven(obj,args) 
  14. 14.            { 
  15. 15.                var numberPattern=/\d+/; 
  16. 16.                //由于控件的ValidateEmptyText设置为true 
  17. 17.                //所以当控件没有值时进行客户端验证 
  18. 18.                if(!numberPattern.test(args.Value)) 
  19. 19.                { 
  20. 20.                    args.IsValid=false;//表示未通过验证,出现错误提示 
  21. 21.                } 
  22. 22.                else if(args.Value%2==0
  23. 23.                { 
  24. 24.                    args.IsValid=true;//表示通过验证,不出现错误提示 
  25. 25.                } 
  26. 26.                else 
  27. 27.                { 
  28. 28.                    args.IsValid=false;//表示未通过验证,出现错误提示 
  29. 29.                } 
  30. 30.            } 
  31. 31.             
  32. 32.            function CheckMultiple3(obj,args) 
  33. 33.            { 
  34. 34.                //由于控件的ValidateEmptyText没有设置,使用了默认值false 
  35. 35.                //所以当控件没有值时不进行客户端验证 
  36. 36.                var numberPattern=/\d+/; 
  37. 37.                if((!numberPattern.test(args.Value))||(args.Value%3!=0)) 
  38. 38.                { 
  39. 39.                    args.IsValid=false
  40. 40.                } 
  41. 41.                else 
  42. 42.                { 
  43. 43.                    args.IsValid=true
  44. 44.                } 
  45. 45.            } 
  46. 46.        </script> 
  47. 47.    </head> 
  48. 48.    <body> 
  49. 49.        <form id="form1" runat="server"
  50. 50.        <div> 
  51. 51.        <table border="1" width="600"
  52. 52.        <tr><td colspan="2" align="center">CustomValidator验证控件用法的例子</td></tr> 
  53. 53.        <tr><td> 
  54. 54.            填一个3的倍数</td><td> 
  55. 55.            <asp:TextBox ID="txtOdd" runat="server"></asp:TextBox> 
  56. 56.            <asp:CustomValidator ID="CustomValidator2" runat="server" ControlToValidate="txtOdd" 
  57. 57.                ErrorMessage="请输入3的倍数" ClientValidationFunction="CheckMultiple3" Display="Dynamic" OnServerValidate="CustomValidator2_ServerValidate"></asp:CustomValidator></td></tr> 
  58. 58.        <tr><td> 
  59. 59.            填一个偶数</td><td> 
  60. 60.            <asp:TextBox ID="txtEven" runat="server"></asp:TextBox> 
  61. 61.                <asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="txtEven" 
  62. 62.                    ErrorMessage="请输入偶数" ClientValidationFunction="CheckEven" ValidateEmptyText="True" OnServerValidate="CustomValidator1_ServerValidate"></asp:CustomValidator></td></tr> 
  63. 63.            <tr><td> 
  64. 64.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  65. 65.        </td><td> 
  66. 66.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  67. 67.        </table> 
  68. 68.        </div> 
  69. 69.        </form> 
  70. 70.    </body> 
  71. 71.    </html>

此外,还编写了服务器端验证方法,下面是后台代码:

  1. 1.    using System; 
  2. 2.    using System.Data; 
  3. 3.    using System.Configuration; 
  4. 4.    using System.Collections; 
  5. 5.    using System.Web; 
  6. 6.    using System.Web.Security; 
  7. 7.    using System.Web.UI; 
  8. 8.    using System.Web.UI.WebControls; 
  9. 9.    using System.Web.UI.WebControls.WebParts; 
  10. 10.    using System.Web.UI.HtmlControls; 
  11. 11.    
  12. 12.    public partial class CustomValidatorDemo : System.Web.UI.Page 
  13. 13.    { 
  14. 14.        protected void Page_Load(object sender, EventArgs e) 
  15. 15.        { 
  16. 16.    
  17. 17.        } 
  18. 18.        //用于验证控件值是否为3的倍数 
  19. 19.        protected void CustomValidator1_ServerValidate(object source, ServerValidateEventArgs args) 
  20. 20.        { 
  21. 21.            System.Text.RegularExpressions.Regex regex=new System.Text.RegularExpressions.Regex("\\d+"); 
  22. 22.            //先用正则判断用户输入的是否能转换成数字 
  23. 23.            if (!regex.IsMatch(args.Value)) 
  24. 24.            { 
  25. 25.                args.IsValid = false;//表示验证不通过 
  26. 26.            } 
  27. 27.            else 
  28. 28.            { 
  29. 29.                //如果对3取模为0就是3的倍数 
  30. 30.                args.IsValid = (int.Parse(args.Value) % 3 == 0); 
  31. 31.            } 
  32. 32.        } 
  33. 33.        //用于验证控件值是否为偶数 
  34. 34.        protected void CustomValidator2_ServerValidate(object source, ServerValidateEventArgs args) 
  35. 35.        { 
  36. 36.            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("\\d+"); 
  37. 37.            //先用正则判断用户输入的是否能转换成数字 
  38. 38.            if (regex.IsMatch(args.Value)) 
  39. 39.            { 
  40. 40.                args.IsValid = false
  41. 41.            } 
  42. 42.            else 
  43. 43.            { 
  44. 44.                //如果对3取模为0就是3的倍数 
  45. 45.                args.IsValid=(int.Parse(args.Value) % 2 == 0); 
  46. 46.            } 
  47. 47.        } 
  48. 48.    
  49. 49.         
  50. 50.    }

以下是什么也不填写时的验证效果:
 
在上图中,由于验证奇偶性的CustomValidator 验证控件设置了ValidateEmptyText 属性为true ,所以即使所验证的控件是空值时也会执行客户端验证。从这个例子中可以看出CustomValidator 验证控件可以不需要RequiredFieldValidator 控件就能实现必填验证,只要将它的ValidateEmptyText 属性设为true 即可。

ValidationSummary 控件
ValidationSummary 控件是用于显示验证所有验证错误摘要的控件,当我们将验证控件的Display 属性设置None 的时候,验证错误信息就在这里显示。
ValidationSummary 控件有三个常见属性:

属性名

说明

DisplayMode

指定显示模式,有BulletList 、List 、SingleParagraph 三种模式

ShowMessageBox 

是否以客户端提示框的信息显示验证错误信息摘要

ShowSummary

 是否在网页中采用内联方式显示错误摘要

 下面是一个ValidationSummary 控件的例子( 在使用ValidationSummary 控件的时候一定要将验证控件的Display 属性设为None ):

  1. 1.    <%@ Page Language="C#" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <script runat="server"
  6. 6.    
  7. 7.    </script> 
  8. 8.    
  9. 9.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  10. 10.    <head runat="server"
  11. 11.        <title>ValidationSummary控件的例子</title> 
  12. 12.    </head> 
  13. 13.    <body> 
  14. 14.        <form id="form1" runat="server"
  15. 15.        <div> 
  16. 16.        <table border="1" width="600"
  17. 17.        <tr><td colspan="2" align="center">旅游活动申请表</td></tr> 
  18. 18.        <tr><td> 
  19. 19.            开始时间</td><td> 
  20. 20.            <asp:TextBox ID="txtStartDate" runat="server"></asp:TextBox> 
  21. 21.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtStartDate" 
  22. 22.                ErrorMessage="用户名必须填写" Display="None"></asp:RequiredFieldValidator> 
  23. 23.                <asp:CompareValidator ID="CompareValidator1" runat="server" ErrorMessage="开始日期必须早于结束日期" ControlToCompare="txtStartDate" ControlToValidate="txtEndDate" Operator="GreaterThanEqual" Type="Date" Display="None"></asp:CompareValidator></td></tr> 
  24. 24.        <tr><td> 
  25. 25.            结束时间</td><td> 
  26. 26.            <asp:TextBox ID="txtEndDate" runat="server"></asp:TextBox> 
  27. 27.            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtEndDate" 
  28. 28.                ErrorMessage="请填写结束时间" Display="None"></asp:RequiredFieldValidator> 
  29. 29.                </td></tr> 
  30. 30.        <tr><td> 
  31. 31.           参加人数</td><td> 
  32. 32.            <asp:TextBox ID="txtNumber" runat="server"></asp:TextBox> 
  33. 33.               <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="txtNumber" 
  34. 34.                   ErrorMessage="必须填写人数" Display="None"></asp:RequiredFieldValidator> 
  35. 35.               <asp:CompareValidator ID="CompareValidator2" runat="server" ControlToValidate="txtNumber" 
  36. 36.                   ErrorMessage="人数必须大于0" Operator="GreaterThan" Type="Integer" ValueToCompare="0" Display="None"></asp:CompareValidator></td></tr> 
  37. 37.            <tr><td> 
  38. 38.                经费预算</td><td> 
  39. 39.                <asp:TextBox ID="txtMoney" runat="server"></asp:TextBox> 
  40. 40.                    <asp:CompareValidator ID="CompareValidator3" runat="server" ControlToValidate="txtMoney" 
  41. 41.                        ErrorMessage="经费必须是大于0的数字" Type="Currency" ValueToCompare="0" Display="None" Operator="GreaterThan"></asp:CompareValidator></td></tr> 
  42. 42.            <tr><td> 
  43. 43.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  44. 44.        </td><td> 
  45. 45.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  46. 46.        </table> 
  47. 47.        </div> 
  48. 48.            <asp:ValidationSummary ID="ValidationSummary1" runat="server" DisplayMode="SingleParagraph" 
  49. 49.                ShowSummary="False" /> 
  50. 50.        </form> 
  51. 51.    </body> 
  52. 52.    </html>

在上面的例子中ValidationSummary 控件的ShowMessageBox 属性采用了默认值false ,并且ShowSummary 采用了默认属性true ,以下是什么也不填写时提交表单的效果:
 
如果我们将上面的例子中的ValidationSummary 控件的ShowMessageBox 属性设为true 并且ShowSummary 属性设置为false ,提交空表单时会得到如下效果:
 

分组校验技术
分组验证技术有助于我们分成组进行验证,默认情况下我们没有设置验证控件的ValidationGroup 属性,那么这些没有设置ValidationGroup 属性的将会算做一个默认分组进行验证。我们看下面的一个例子:

  1. 1.    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Register.aspx.cs" Inherits="Register" %> 
  2. 2.    
  3. 3.    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  4. 4.    
  5. 5.    <html xmlns="http://www.w3.org/1999/xhtml" > 
  6. 6.    <head runat="server"
  7. 7.        <title>无标题页</title> 
  8. 8.    </head> 
  9. 9.    <body> 
  10. 10.        <form id="form1" runat="server"
  11. 11.        <div> 
  12. 12.        <table border="1" width="600"
  13. 13.        <tr><td colspan="2" align="center"
  14. 14.            用户注册</td></tr> 
  15. 15.        <tr><td> 
  16. 16.            用户名</td><td> 
  17. 17.            <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox> 
  18. 18.            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtUserName" 
  19. 19.                ErrorMessage="用户名必须填写" Display="Dynamic"></asp:RequiredFieldValidator> 
  20. 20.                </td></tr> 
  21. 21.        <tr><td> 
  22. 22.            密码</td><td> 
  23. 23.            <asp:TextBox ID="txtPassword" runat="server"></asp:TextBox> 
  24. 24.            <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtPassword" 
  25. 25.                ErrorMessage="必须填写密码" Display="Dynamic"></asp:RequiredFieldValidator> 
  26. 26.                </td></tr> 
  27. 27.        <tr><td> 
  28. 28.            用户头像</td><td> 
  29. 29.            <asp:TextBox ID="txtHeadImage" runat="server" onfocus="blur();"></asp:TextBox> 
  30. 30.               <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="txtHeadImage" 
  31. 31.                   ErrorMessage="必须上传头像" Display="Dynamic"></asp:RequiredFieldValidator> 
  32. 32.                <asp:FileUpload ID="FileUpload1" runat="server" /> 
  33. 33.                <asp:Button ID="btnUpload" runat="server" Text="上传" /> 
  34. 34.                <asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server" ControlToValidate="FileUpload1" 
  35. 35.                    Display="Dynamic" ErrorMessage="必须选择文件"></asp:RequiredFieldValidator> 
  36. 36.               </td></tr> 
  37. 37.            <tr><td> 
  38. 38.            <asp:Button ID="Button2" runat="server" Text="提交" /> 
  39. 39.        </td><td> 
  40. 40.            <input id="Reset3" type="reset" value="重置" /></td></tr> 
  41. 41.        </table> 
  42. 42.        </div> 
  43. 43.        </form> 
  44. 44.    </body> 
  45. 45.    </html>

它的后台代码如下:

  1. 1.    using System; 
  2. 2.    using System.Data; 
  3. 3.    using System.Configuration; 
  4. 4.    using System.Collections; 
  5. 5.    using System.Web; 
  6. 6.    using System.Web.Security; 
  7. 7.    using System.Web.UI; 
  8. 8.    using System.Web.UI.WebControls; 
  9. 9.    using System.Web.UI.WebControls.WebParts; 
  10. 10.    using System.Web.UI.HtmlControls; 
  11. 11.    
  12. 12.    public partial class Register : System.Web.UI.Page 
  13. 13.    { 
  14. 14.        protected void Page_Load(object sender, EventArgs e) 
  15. 15.        { 
  16. 16.    
  17. 17.        } 
  18. 18.        protected void btnUpload_Click(object sender, EventArgs e) 
  19. 19.        { 
  20. 20.            //判断是否上传了文件 
  21. 21.            if (fileUpload.HasFile) 
  22. 22.            { 
  23. 23.                //指定上传文件在服务器上的保存路径 
  24. 24.                string savePath = Server.MapPath("~/upload/"); 
  25. 25.                //检查服务器上是否存在这个物理路径,如果不存在则创建 
  26. 26.                if (!System.IO.Directory.Exists(savePath)) 
  27. 27.                { 
  28. 28.                    //需要注意的是,需要对这个物理路径有足够的权限,否则会报错 
  29. 29.                    //另外,这个路径应该是在网站之下,而将网站部署在C盘却把上传文件保存在D盘 
  30. 30.                    System.IO.Directory.CreateDirectory(savePath); 
  31. 31.                } 
  32. 32.                savePath = savePath + "\\" + fileUpload.FileName; 
  33. 33.                fileUpload.SaveAs(savePath);//保存文件 
  34. 34.                //不过需要注意的是,在客户端访问却需要指定的是URL地址,而不是在服务器上的物理地址 
  35. 35.                txtHeadImage.Text = string.Format("<a href='upload/{0}'>upload/{0}</a>", fileUpload.FileName); 
  36. 36.            } 
  37. 37.        } 
  38. 38.    }

注意在页面中笔者使用了javascript 技术让头像文本框无法输入,只能在用户上传头像成功之后才会自动设置成用户上传成功后头像URL 地址。
这个页面的运行效果如下:
 
在这个页面中这个页面是很难按照正常方式注册成功的,因为要想上传头像成功则必须表单中所有字段都填写了,而用户头像一栏又是必须用户上传头像成功之后自动成为上传的头像在服务器端的URL 地址的。当我们选择一个本地头像点“ 上传” 按钮时的效果:



同样点“ 提交” 按钮也不能上传成功。这种情况下我们就可以使用分组技术,将验证上传控件的验证控件和上传按钮的ValidationGroup 属性设为同一个值(按住Ctrl 键同时选择上述两个控件),如下图:



这样点“ 上传” 按钮的时候只有ValidationGroup 属性与该按钮的ValidationGroup 属性一致的按钮才会验证所关联的控件的值,这样用户头像才能上传成功,如下图:
 
这样当用户天按要求填写好其它信息后就能点击“ 提交” 按钮进行注册了。

总结:
为了检验用户填写的数据的正确性,我们有两种办法:采用传统办法,自己编写客户端脚本进行验证;使用asp.net 中的验证控件来进行验证。
CompareValidator 控件、RangeValidator 控件和RegularExpressionValidator 控件对所关联的验证的空值是不进行验证的(即能通过验证),如果要求用户必须输入并且还要符合规则就要结合RequiredFieldValidator 控件共同验证。
如果验证的规则比较复杂,则可以使用CustomValidator 控件自己编写客户端验证代码来进行验证,如果要让CustomValidator 控件对空值也进行客户端验证则要设置它的ValidateEmptyText 属性为true 。
个人经验:对于日期类的验证不建议使用正则进行验证,如果按照“yyyy-mm-dd” 这样的形式对日期采用正则验证,那么“2008-02-31” 这样值也是能通过验证的,虽然可以可以编写更严格的正则验证也是可以的(笔者曾经见过,正则表达式长度近千字节了,而且非常难以理解),其实用RangeValidator 控件就能实现轻松验证,将它的Type 属性设置为Date ,并将的最大值和最小值分别设置为“9999-12-31” 和“0001-01-01” 就能避免出现2008-02-31” 这样的值。也就是掌握了它们的规则灵活运用它们进行数据验证,提高数据的有效性。

--------------------------------------------------------------

后记:写这篇真有点吃力,查阅了大量有关正则方面的资料,调试N 多次才将效果调试出来,历史4 、5 天的无数次失败的尝试得到了想要给大家展示的效果(知识点涉及CSS 和javascript 及正则等等),也算是不枉费大家的鼓励和希望了。我希望大家每次看的时候总能看到一些对实际开发有帮助但是以前没有用过或者没有想到的解决问题的思路和方法。

posted on 2011-12-30 17:08  易尔购  阅读(823)  评论(0编辑  收藏  举报