5.3 ASP.NET 4.5验证控件
Web网站中进行数据验证非常重要,但是用脚本语言来实现这一功能是一件非常繁琐的事,ASP.NET 4.5提供了功能强大的验证控件用于用户的输入,利用这些控件,开发人员可以轻松地实现对用户输入的验证。
5.3.1 数据验证的两种方式
Web网站中进行数据验证有两种方式。在窗体回送给服务器之前,对输入该窗体上的数据进行的验证称为“客户端验证”。当请求发送到应用程序所在的服务器后,在请求/相应循环的这一刻,就可以为所提交的信息进行有效性验证,这称为“服务器端验证”。
1.服务器端数据验证
服务器端进行数据验证的控件在服务器代码中执行输入检查。服务器将逐个调用验证控件来检查用户输入。如果在任意输入控件中检测到验证错误,则该页面将自行设置为无效状态,以便在代码运行之前测试其有效性。验证发生的时间是:已对页面进行了初始化(即,处理了视图状态和回发数据),但尚未调用任何更改或单击事件处理程序时。
通过像添加其他服务器控件那样向页面添加验证控件,即可启用对用户输入的验证。有各种类型的验证控件,如范围检查或模式匹配验证控件。每个验证控件都引用页面上其他地方的输入服务器控件。处理用户输入时,验证控件会对用户输入进行测试,并设置属性以指示该输入是否通过测试。调用了所有验证控件后,会在页面上设置一个属性以指示是否出现了验证检查失败的情况。
可将验证控件关联到验证组中,使得属于同一组的验证控件可以一起进行验证。可以使用验证组有选择地启用或禁用页面上相关控件的验证。关于验证组,不在这里介绍,感兴趣的读者可以参考相关资料。
可以使用自己的代码来测试页和单个控件的状态。例如,可以在使用用户输入的信息更新数据记录之前来测试验证控件的状态。如果检测到状态无效,将会略过更新。通常,如果任何验证检查失败,都将跳过所有处理过程并将页面返回给用户。检测到错误的验证控件后,将生成显示在页上的错误信息。可以使用ValidationSummary控件在一个位置显示所有验证错误。
每个验证控件通常只执行一次测试。但可能需要检查多个条件。例如,可能需要指定必需的用户输入,同时将该用户输入限制为只接受特定范围内的日期。此时,可以将多个验证控件附加到页面上的一个输入控件。通过使用逻辑AND运算符来解析控件执行的测试,这意味着用户输入的数据必须通过所有测试才能视为有效。
验证控件通常在呈现的页面中不可见。但是,如果控件检测到错误,则它将显示指定的错误信息文本。错误信息可以以各种方式显示,如下所示。
● 内联方式:每一验证控件可以单独地(通常在发生错误的控件旁边)显示一条错误信息。
● 摘要方式:验证错误可以收集并显示在一个位置,例如页面的顶部。这一策略通常与在发生错误的输入字段旁显示消息的方法结合使用。如果用户使用Internet Explorer 4.0或更高版本,则摘要可以显示在消息框中。
● 就地和摘要方式:同一错误信息的摘要显示和就地显示可能会有所不同。可使用此选项就地显示简短错误信息,而在摘要中显示更为详细的信息。
● 自定义方式:通过捕获错误信息并设计自己的输出来自定义错误信息的显示。
服务器端数据验证相对很安全,因为这种验证是基于服务器端的验证,不容易被绕过,而且也可以不考虑客户端的浏览器是否支持客户端脚本语言,一旦提交的数据无效,页面就会回送的到客户机上。由于页面必须提交到一个远程位置进行检验,这使得服务器端的验证过程比较慢。
2.客户端数据验证
客户端数据验证通常是对客户端浏览器中窗体上的数据进行验证,是通过客户端浏览器传送的页面提供的一个脚本,通常采用的是JavaScript形式,在窗体回送到服务器之前,对数据进行验证。
客户端数据验证的突出优点是能够快速的向用户提供验证结果的反馈,当用户的信息输入有错误时,可以立即显示一条错误信息,而不需要将这些数据传输到服务器,减少了服务器处理的压力。但是客户端的验证没有直接访问数据库的功能,无法实现用户合法性的验证。用户可以很容易地查看到页面的代码,而且有可能伪造提交的数据,如果浏览器版本过低或浏览器禁用了客户端脚本,客户端验证就无效了。对于一些黑客而言可以很方便地绕过客户端的验证,所以,仅仅依靠客户端的验证是不安全的。
默认情况下,在执行客户端验证时,如果页面上出现错误,则用户无法将页面发送到服务器。但有时需要即使在出错时也允许用户发送。例如,页面上可能有一个取消按钮或一个导航按钮,即使在部分控件未通过验证的情况下,也需要该按钮提交页面。此时,需要对ASP.NET 4.5服务器控件禁止验证。因本书不涉及对JavaScipt脚本语言的介绍,所以关于客户端数据验证的内容在此仅一笔带过。
比较好的方法是先进行客户端验证,在窗体发送给服务器后,再使用服务器端验证进行检查,这种方法综合了两种验证的优点,总是执行服务器端验证(对于ASP.NET 4.5验证控件无论如何都不可关闭这种验证)。如果知道客户端使用JavaScript,则客户端验证是额外的便利措施。如果一些客户端没有启用JavaScript,仍然可以打开EnableClientScript,它将被浏览器忽略。
5.3.2 6种验证控件
ASP.NET 4.5的服务器验证控件共有6种,分别用于检查用户输入信息的不同方面,各种控件的类型和作用如表5-2所示。
表5-2 验证控件分类
对于一个输入控件,可以附加多个验证控件。既可以验证某个控件是必需的,而且还可以验证该控件必须包含特定范围的值。
1.RequiredFieldValidator控件
RequiredFieldValidator控件通常用于在用户输入信息时,对必选字段进行验证。在页面中添加RequiredFieldValidator控件并将其链接到必选字段控件(通常是TextBox控件)。在控件失去焦点时,如果其初始属性值没有被改变,将会触发RequiredFieldValidator控件。RequiredFieldValidator控件的使用语法定义如下所示:
对于RequiredFieldValidator控件的使用一般是通过设置其属性来完成的,该控件常用的属性如表5-3所示。
表5-3 RequiredFieldValidator控件的常用属性
(续表)
可被验证的标准控件包括TextBox、ListBox、DropDownList、RadioButtonList以及一些HTML服务器控件。
RequiredFieldValidator控件默认检查非空字符串。在RequiredFieldValidator关联的表单字段中输入任何字符,该RequiredFieldValidator控件就不会显示它的验证错误信息。可以使用RequiredFieldValidator控件的InitialValue属性来指定空字符串之外的默认值。
【实例5-7】RequiredFieldValidator验证控件的使用
使用RequiredFieldValidator控件最常用的场合是用户登录页面,可进行验证用户名和密码的输入是否为空的操作,本例通过这个操作来学习该控件的应用。
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例5-7”。
02 在“实例5-7”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“设计视图”,进入“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中第2行添加一个服务器文本框控件TextBox1接受用户的输入。第3行添加了一个服务器RequiredFieldValidator控件,分别设置需验证的关联控件、显示方式和错误提示的文字和颜色。第4行添加一个服务器文本框控件TextBox2接受用户输入密码并设置文本框的模式显示密码格式。第5添加了一个服务器RequiredFieldValidator控件,分别设置需验证的关联控件TextBox2、显示方式和错误提示的文字和颜色。第6行添加一个服务器按钮控件Button1并设置其单击事件Click。第7行添加一个服务器标签控件Label1。
04 单击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上述代码第1行定义处理按钮控件Button单击事件Click的方法。第2行判断如果用户输入的用户名是admin,同时密码输入是888888,则第3行在Label1控件上显示登录成功的提示文字。否则第6行在Label1控件上显示登录失败的提示文字。
05 按快捷键Ctrl+F5运行程序,如图5-15所示。如果用户没有输入任何内容就单击“登录”按钮,出现RequiredFieldValidator控件的红色验证错误提示的文字。
图5-15 运行结果1
如果用户在两个文本框中输入正确的用户名和密码,单击“登录”按钮,显示如图5-16所示的登录成功提示。
图5-16 运行结果2
2.CompareValidator控件
CompareValidator控件用于将用户输入的值和其他控件的值或者常数进行比较,以确定这两个值是否与由比较运算符(小于、等于、大于等等)指定的关系相匹配。还可以使用CompareValidator控件来指示输入到输出控件中的值是否可以转换为BaseCompareValidator.Type属性所指定的数据类型。CompareValidator控件的使用语法定义如下所示:
对于CompareValidator控件的使用一般也是通过对其属性设置来完成的,该控件常用的属性如表5-4所示。
表5-4 CompareValidator控件的常用属性
【实例5-8】CompareValidator验证控件的使用
在网站密码修改中,有一个最常用的比较,就是对用户输入修改密码的两次验证,这就需要用到上面的CompareValidator控件,本例就来实现这一常用功能。
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例5-8”。
02 在“实例5-8”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“设计视图”,进入“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中第2、3、4行各添加一个服务器文本框控件TextBox接受用户的输入密码。第5行添加了一个服务器验证控件CompareValidator1,分别设置需验证的关联控件、需比较的控件、控件显示方式和错误提示的文字和颜色。第6行添加一个服务器按钮控件Button1并设置其单击事件Click。第7行添加一个服务器标签控件Label1。
04 单击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上面的代码中第1行定义处理按钮控件Button单击事件Click的方法。第2行判断如果两个密码文本框中输入的内容相同,则第3行在Label1控件上显示密码修改成功的提示文字。
05 按快捷键Ctrl+F5运行程序,效果如图5-17所示。用户输入的两次密码不同,单击“提交”按钮后,显示CompareValidator控件的红色错误提示文字。
图5-17 运行结果1
用户输入的两次密码一致,则显示如图5-18所示的密码修改成功的提示。
图5-18 运行结果2
3.RangeValidator控件
RangeValidator控件用于测试输入控件的值是否在指定范围内。在实际应用中,有时需要用户在一定范围内输入某个值,例如用户输入的年龄应该大于1小于200,这时就需要使用RangeValidator控件。RangeValidator控件的使用语法定义如下所示。
对于RangeValidator控件的使用一般也是通过对其属性设置来完成的,该控件常用的属性如表5-5所示。
表5-5 RangeValidator控件的常用属性
【实例5-9】RangeValidator验证控件的使用
在考试成绩管理模块中,经常需要用户输入考试的成绩,事实上成绩不可能无限大,因此就需要对输入的成绩值进行验证。本例使用RangeValidator控件对输入的成绩值进行控制。
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例5-9”。
02 在“实例5-9”中创建一个名为Default.aspx的窗体
03 单击网站目录下的Default.aspx文件,进入“视图编辑”界面,打开“设计视图”,进入“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中第2行添加一个服务器文本框控件TextBox1接受用户输入的成绩。第3行添加一个服务器按钮控件Button1并设置其单击事件Click。第4行添加一个服务器标签控件Label1。第5行添加了一个服务器验证控件RangeValidator1,分别设置需验证的关联控件、控件显示方式、错误提示的文字和颜色、验证值的数据类型以及值的最大最小范围。
04 单击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上面的代码中第1行定义处理按钮控件Button单击事件Click的方法。第2行使用验证控件对象RangeValidator1的IsValid属性获得文本框中的值,判断如果该值已经通过验证,则第3行标签控件上显示录入成功的信息。否则,不在控件中显示任何内容。
05 按快捷键Ctrl+F5运行程序,效果如图5-19所示。用户输入的成绩值超过验证的范围,单击“提交”按钮后,显示RangeValidator1控件的红色错误提示文字。
图5-19 运行结果1
如果用户输入的成绩值范围正确。单击“提交”按钮后,显示如图5-20所示的成绩录入成功的提示。
图5-20 运行结果2
4.RegularExpressionValidator控件
RegularExpressionValidator控件由于涉及到了编程常用知识——正则表达式,所以在所有的验证控件中是比较复杂的,本节将结合正则表达式的基础内容来介绍RegularExpressionValidator控件。
(1)RegularExpressionValidator控件简介
RegularExpressionValidator控件用于验证相关输入控件的值是否匹配正则表达式指定的模式。在实际的应用中,经常需要用户输入一些固定格式的信息,例如电话号码、邮政编码、网址等内容。为了保证用户输入符合规定的要求,例如电话号码,美国、欧洲和中国的表示方法都各不相同,此时就需要使用RegularExpressionValidator控件进行验证。RegularExpressionValidator控件的使用语法定义如下所示:
对于RegularExpressionValidator控件的使用一般也是通过对其属性设置来完成的,该控件常用的属性如表5-6所示。
表5-6 RegularExpressionValidator控件的常用属性
(2)正则表达式
由于RegularExpressionValidator控件的ValidationExpression属性需要开发人员设置用在表达式描述的预定义格式,所以,本节将简单介绍一些正则表达式的基础知识。
正则表达式(Regular Expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。简单的说就是用某种模式去匹配一类字符串的公式。它是由普通字符(例如字符A~Z)以及特殊字符(称为元字符)组成的文字模式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
①普通字符
普通字符分为打印字符和非打印字符两种。打印字符包含所有的大小写字母、0~9的数字以及所有的标点字符。非打印字符如表5-7所示。
表5-7 非打印字符
②特殊字符
所谓特殊字符,就是一些有特殊含义的字符,比如Windows笔记本文件命名的默认格式“*.txt”中的“*”就是一个特殊字符,它表示一个任何字符串的意思。表5-8中列举了正则表达式中特殊字符的含义。
表5-8 特殊字符
(续表)
③各种操作符的优先级
相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如表5-9所示。
表5-9 操作符的的优先等级
④应用举例
通过分析匹配中国的电话号码的正则表达式来看如何使用其进行字符匹配,表达式如下所示:
正则表达式说明:电话号码由三位区号和8位号码组成,类似(021)12345678或者是021-12345678的两种字符串都被认为是合法的电话号码。可以看到正则表达式中的“(\(\d{3}\)”部分,“\(”和“\)”使用转义字符“\”分别匹配左、右括号,而中间的“\d{3}”则表示由三个数字组成的字符串。所以这一部分匹配了的是“3位数字的区号”。上面正则表达式中的“\d{3}-”匹配的就是“3位数字的区号加一个横杠”。这两个部分之间使用一个“|”来连接,表示这二者取其一。所以“(\(\d{3}\)|\d{3}-)”整个匹配的是电话号码的区位部分。
正则表达式中的“?”表示区号出现1次或0次。后面部分中的“\d”匹配一个字符串;“{8}”表示出现8次非负数的正数,所以“\d{8}”整个部分表示由8位数字组成的字符串,匹配后面的8位电话号码。
上面的这个例子比较简单,实际操作中有些正则表达式的定义非常复杂。由于本书内容重点不在此,所以仅做一个简单的说明,目的是让大家对正则表达式有一个初步的认识。如果读者想学习正则表达式的详细内容,请参考相关专门的书籍。
【实例5-10】RegularExpressionValidator验证控件的使用
本例使用RegularExpressionValidator控件验证用户输入的邮箱格式是否匹配指定的模式。添加一个文本框供用户输入邮箱地址,由于邮箱是有固定格式的,为了防止用户输入非法格式,我们使用一个RegularExpressionValidator控件来验证用户输入的内容。
01 启动Visual Studio 2012,创建一个ASP.NET Web空应用程序,命名为“实例5-10”。
02 在“实例5-10”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“设计视图”,进入“源视图”,在编辑区中<form></form>标记之间编写如下代码。
上面的代码中第2行添加一个服务器文本框控件TextBox1接受用户输入的邮箱地址。第2行添加一个服务器按钮控件Button1并设置其单击事件Click。第5行添加了一个服务器验证控件RegularExpressionValidator,分别设置需验证的关联控件TextBox1、控件显示方式为动态、错误提示的文字和颜色、最关键的是设置ValidationExpression属性即验证邮箱地址格式为“\d{17}[\d|X]|\d{15}”。第7行添加一个服务器标签控件Label1显示提示信息。
04 双击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上面的代码中第1行定义处理按钮控件Button单击事件Click的方法。第2行使用验证控件RegularExpressionValidator1对象的RangeValidator1的IsValid属性获得文本框中的值,判断如果该值已经通过验证,则第3行标签控件上显示通过验证的信息。否则,不在控件中显示任何内容。
05 按快捷键Ctrl+F5运行程序,效果如图5-21所示。当用户输入不正确格式的邮箱地址,单击“提交”按钮后,显示RegularExpressionValidator1控件的红色错误提示文字。
图5-21 运行结果1
如果用户输入邮箱地址的格式正确,单击“提交”按钮后,显示如图5-22所示的成功通过验证的提示。
图5-22 运行结果2
5.CustomValidator控件
有时使用现有的验证控件可能满足不了开发人员的需求,因此有时可能需要开发人员自己来编写验证函数,而通过CustomValidator控件的服务器端事件可以将该验证函数绑定到相应的控件。CustomValidator控件的使用语法定义如下:
对于CustomValidator控件的使用一般也是通过对其属性设置来完成的,该控件常用的属性如表5-10所示。
表5-10 CustomValidator控件的常用属性
(续表)
可以通过处理ServerValidate事件来将自定义验证函数和CustomValidator控件相关联。这个控件引发称为ServerValidate的事件,可以使用该事件执行实际的测试。输入值将作为ServerValidateEventArgs.Value传递给过程。可以设置一个Boolean值,表示ServerValidate EventArgs.IsVaild中过程的结果。如果该属性设置为false,CustomValidator将像任何其他验证控件对输入测试失败的情况进行相应操作。
在事件处理程序的实现中,应该引用ServerValidateEventArgs.Value属性而不是直接引用控件。这就可以对多个具有潜在不同的ControlToValidate设置的CustomValidator共享共同的事件处理程序。
对于服务器端自定义验证。要将自定义验证放置在验证程序的OnServerValidalk委托中,为执行验证的ServerValidate事件提供一个处理程序。作为参数传递到该事件处理程序的ServerValidateEventArgs对象的Value属性是要验证的值。IsValid属性是一个布尔值,用于设置验证的返回结果。
对于客户端自定义验证,首先要添加前面描述的服务器端验证函数。然后,将客户端验证脚本加到页面中。如果不为CustomValidator控件关联一个客户端验证函数,那么要到页面回传到服务器端后,CustomValidator控件才会呈现错误信息。此外,如果有任何的验证错误,其他的验证控件都将阻止页面表单回传,所以需通过页面中其他验证检查后,才能看到CustomValidator控件呈现的错误信息。使用ClientValidationFunction属件指定与CustomValidator控件关联的客户端验证脚本函数的名称。
【实例5-11】CustomValidator控件的使用
本例使用CustomValidator控件来实现上例5-10相同的功能,具体实现步骤如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web应用程序,命名为“例5-11”。
02 在“实例5-11”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中第2行添加一个服务器文本框控件TextBox1接受用户输入的邮箱地址。第3行添加一个服务器按钮控件Button1并设置显示的文本。第4行添加了一个服务器验证控件CustomValidator1,分别设置需验证的关联控件TextBox1、控件显示方式为动态、错误提示的颜色为红色。最关键的是设置验证控件CustomValidator1的服务器端验证事件ServerValidate。第5行添加一个服务器标签控件Label1显示提示信息。
04 单击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上面的代码中第1行定义自定义验证控件CustomValidator1服务器验证事件ServerValidate的方法。第2行判断如果调用的自定义方法ValidateTextBox返回的值是True,则第3行在标签控件上显示通过输入格式验证的信息。第4行同时将控件的IsValid属性设置为true,表示验证通过。否则,第7行设置验证控件CustomValidator1的错误信息属性,在页面显示错误提示。第8行同时将控件的IsValid属性设置为false,表示验证不能通过。
第11行定义一个返回布尔值ValidateTextBox的方法,参数是用户在文本框中输入的邮箱地址。第12行引入命名空间System.Text.RegularExpressions调用Regex对象的IsMatch方法,该方法用于验证一个正则表达式与指定输入的字符是否匹配,如果正确返回true,否则返回false。
05 按快捷键Ctrl+F5运行程序,运行结果图和例5-10的运行结果完全相同。
6.ValidationSummary控件
ValidationSummary控件用于显示页面中的所有验证错误的摘要。当页面上有很多验证控件时,可以使用一个ValidationSummary控件在一个位置总结来自Web页上所有验证程序的错误信息,这个控件在使用大的表单时特别有用。ValidationSummary控件的使用语法定义如下:
对于ValidationSummary控件的使用一般也是通过对其属性设置来完成的,该控件常用的属性如表5-11所示。
表5-11 ValidationSummary控件的常用属性
这里再比较一下验证控件的ErrorMessage属性和Text属性。
(1)如果有验证失败的情况,通常是在输入控件丢失焦点时,Text值会出现在页面上验证控件所在的位置。
(2)如果有验证失败的情况,通常都是在单击具有CausesValidation=true的Submit按钮时,ErrorMessage值会出现在ValidationSummary控件中。
ValidationSummary控件出现在页面上的回送操作中,并且显示一组错误消息,这些消息来自于IsValid=false的所有验证控件。根据在DisplayMode中的设置,可以将这些错误消息安排为列表、段落或项目符号列表。此外,可以在消息框中显示,通过ShowMessageBox=true/false设置。再次声明,ValidationSummary控件自身实际上不执行任何验证:它没有ControlToValidate属性。
可以将验证错误信息只显示在ValidationSummary验证总结控件中,而在其他的验证控件位置不显示出错的文本消息。通过设置验证控件的Display属性为None值来实现这种隐藏。
【实例5-12】ValidationSummary控件的使用
本例通过使用ValidationSummary控件来汇总验证控件的错误提示信息并进行统一显示处理,具体实现过程如下:
01 启动Visual Studio 2012,创建一个ASP.NET Web应用程序,命名为“实例5-12”。
02 在“实例5-12”中创建一个名为Default.aspx的窗体。
03 单击网站的目录下的Default.aspx文件,进入“视图编辑”界面,打开“源视图”,在编辑区中<form></form>标记之间编写如下代码:
上面的代码中除了添加5个服务器文本框控件、一个服务器按钮控件Button1和一个服务器标签控件Label以外,分别添加了除CustomValidator以外的5种验证控件,其中除ValidationSummary验证控件以外,显示方式Display属性均设置为不显示。ValidationSummary1验证摘要控件,分别设置了边框的颜色、样式和宽带;设置文字的颜色。控件摘要的标题、样式和宽度。
04 单击网站目录下的“Default.aspx.cs”文件,编写代码如下:
上面的代码中第1行定义处理注册按钮的事件Click的方法。第2行判断加载页面通过验证,在标签控件上显示验证成功的提示。
05 按快捷键Ctrl+F5运行程序,结果如图5-23所示。如果有用户未输入用户名、两次密码输入错误、年龄输入和E-mail地址输入不正确的情况,显示ValidationSummary1验证错误的摘要列表。
图5-23 运行结果1
如果用户输入都符合要求,单击“确认”按钮后,显示如图5-24所示的验证成功的提示。
图5-24 运行结果2