本篇要讲述的知识点如下:
数据验证介绍
纯客户端脚本验证
asp.net验证控件概述
RequiredFieldValidator控件
CompareValidator控件
RangeValidator控件
正则表达式
RegularExpressionValidator控件
CustomValidator控件
ValidationSummary控件
分组校验技术
数据验证介绍
在我们的开发中要提高网站的健壮性,为了做到这些笔者曾经在企业培训时候提到了两个原则:
第一条原则:就是尽量减少让用户输入的机会,比如数据的录入时间我们可以设置该条记录的为数据库的当前时间,这个可以在创建或者设计表的时候实现。下面就是一个例子:
- create table ActionLog (
- LogID bigint identity(1,1),
- UserID int not null,
- UserIP varchar(15) not null,
- ActionDate datetime null default getdate(),
- ActionDescription nvarchar(800) not null,
- ActionStatus tinyint not null,
- WebSiteID int not null,
- constraint PK_ACTIONLOG primary key (LogID)
- )
- Go
上面中的ActionDate字段就是设置成自动获取数据库服务器当前时间,这样在插入记录的时候无需在这个字段插入值。如果这个值让用户填写一来可能用户不能按照我们要求的格式填写,二来即使按照我们的要求填写也可能用户不会填写当前时间,如果采用上面的办法就能有效避免这个问题。
第二条原则:就是不要过分相信用户一定会按照我们的要求规规矩矩去做。最终使用我们的软件产品的用户大都计算机水平不高(如果水平高可能就会自己开发了),所以他们可能不太懂得什么格式和要求之类的,这就经常需要对用户填写的数据进行检查。如果我们对用户提交的数据经过充分检查,那么就能有效提高程序的健壮性,这样也能从某些途径堵住了黑客入侵我们系统的路子。
对数据的检查按时机来分可以分为客户端检查和服务器端检查。
在客户端检查是指通过客户端脚本(如javascript脚本或者vbscript脚本)来进行检查,利用客户端脚本检查的好处是减小网络流量、减轻服务器压力和反映迅速。因为客户端脚本是在客户端运行,我们可以定义好检验规则,在客户端就可以完成检验,一旦不能通过验证客户端马上就能得到提示,而不用将整个表单提交到服务器(笔者早些年曾经就有这样的经历:网速28.8K的情况下提交一个注册表单,数分钟后得到服务器的反馈说是用户名不符合要求,当时差点吐血),用户体验非常好。客户端验证也有一些缺点:因为我们的验证规则完全定义在客户端脚本中,不怀好意的窥探者可以从这些客户端代码找出我们脚本的漏洞或者某些跳过脚本验证的方法,从而造成网站的健壮性出现问题,这就对客户端代码的客户端脚本编程能力提出了挑战。另外客户端验证可能会使我们写得非常优秀的代码在短短几天流传整个网络,不能进行版权控制。
在服务器端检查是指将表单提交到服务器后在服务器上用服务器端代码进行验证(如用C#或者VB.NET等),服务器端验证的优点是我们的验证规则对用户来说是一个黑匣子,比较难找出我们验证代码的漏洞,并且服务器端验证的代码编写起来相对客户端脚本要容易得多,但是服务器端验证也有缺点:那就是大量的复杂验证会降低服务器的性能。
因此一般验证办法都是上面两种样式结合,利用客户端验证建立验证的第一道关卡,这个关卡将大量无意中填写的不符合要求的数据阻止在客户端,然后在服务器端建立第二道关卡,将那些利用了我们的客户端脚本漏洞的数据阻止在保存之前。
客户端脚本验证
下面是一个利用客户端脚本在客户端进行验证的例子。我们对Button服务器控件的OnClientClick加上一个客户端验证方法,只有当这个客户端方法返回true的时候表单才会向服务器提交,如果用户填写的数据不符合要求就返回false值。
下面是前台代码(后台没有编写任何代码):
- <%@ Page Language="C#" AutoEventWireup="true" CodeFile="ClientValidate.aspx.cs" Inherits="ClientValidate" %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head runat="server">
- <title>纯客户端脚本验证的例子</title>
- <script language="javascript" type="text/javascript">
- //当这个方法返回false的情况下就不会向服务器提交数据
- function checkForm()
- {
- //如果没有填写任何数据
- if(document.form1.txtUserName.value=="")
- {
- alert("用户名不能为空!");
- return false;
- }
- var length=document.form1.txtUserName.value.length;
- //如果填写内容长度不在6到10字符之间
- if(length<6||length>10)
- {
- alert("用户名必须是6到10个字符!");
- return false;
- }
- else
- {
- return true;
- }
- }
- </script>
- </head>
- <body>
- <form id="form1" runat="server">
- <div>
- <table border="0">
- <tr><td>用户名</td><td><asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td></tr>
- <tr><td><asp:Button ID="btnOK" runat="server" Text="提交" OnClientClick="javascript:return checkForm();" OnClick="btnOK_Click" /></td><td><input type="reset" value="清空" /></td></tr>
- </table>
- </div>
- </form>
- </body>
- </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,� |