第4章 ASP.NET验证控件

无论什么应用软件系统,它最本质的功能用途就是处理数据。这样,数据的安全性就成了系统设计中非常重要的话题,提交一些不安全的数据(如SQL注入、数据类型或者数据范围不适合等)常常会导致系统崩溃或者系统计算结果不正确等严重后果。因此,这就要求在设计系统数据录入与提交功能时必须对数据的合法性进行验证,以保证干净准确的数据流入系统。本章将介绍数据验证的相关知识,并重点讲解ASP.NET数据验证控件的使用。

4.1 验证控件概述

有过Web开发经验的朋友应该知道,以前对于数据输入的合法性验证使用最多的应该属于客户端的JavaScript脚本验证方法了。这种方法就是当用户通过网页控件输入数据后,再通过一段客户端验证脚本JavaScript对数据的合法性进行验证。如果输入的数据有问题,用户会在表单被回送到服务器之前立即得到验证的通知信息。这种验证方法的最大好处就是节省服务器资源,验证的速度快。但它也有致命的弱点,因为它是把JavaScript脚本验证方法直接写在页面上的,所以一个精通技术的攻击者可以通过下载该页面代码来删除验证输入数据的客户端JavaScript脚本方法,并保存新的页面,然后使用该页面来提交伪造的数据来进行系统攻击,那么系统将变得脆弱无比。

面对JavaScript脚本验证方法的不足,大部分开发者选用了服务器端验证方法进行弥补。虽然服务器端验证方法相对于JavaScript脚本验证方法的安全性更高,但会让你写很多的验证代码。不论从代码量还是服务器资源的消耗上来说,过多的验证逻辑都是很不理想的。因此,微软在ASP.NET中提供了一系列用于数据验证的验证控件来解决这些问题。这些控件在Web页面中声明,然后绑定到页面的数据输入控件里。当验证控件和输入控件绑定之后,验证控件将自动执行客户端和服务器端的验证,而我们所做的就是在验证控件里设置好数据的验证规则与相应的验证提示。如果相应页面输入控件的数据为空、不包含正确的数据类型或者不遵守指定的验证规则,那么验证控件将完全阻止页面回送,并返回相应的验证提示。

4.1.1 验证控件的类型

在ASP.NET中,提供了6种类型的验证控件,例如范围检查、模式匹配等验证控件,如表4-1所示。每个验证控件都引用网页上的数据输入控件,这些数据输入控件必须是ASP.NET服务器控件。当用户在数据输入控件里输入数据并进行提交时,验证控件会对用户输入的数据进行测试,并设置属性,以指示输入是否通过了测试。调用了所有验证控件后,会在网页上设置一个属性以指示是否出现验证检查失败。

在开发中,可以使用自己的代码来测试网页和各个控件的状态。还可以将验证控件和客户的自定义规则一起工作,这可以重用代码并使代码模块化。

figure_0132_0093

当然,也可以在同一个数据输入控件里面使用多个验证控件。例如,用一个RequiredFieldValidator验证控件来验证数据输入控件的数据是否为空,用一个RangeValidator验证控件来检查数据输入控件里的数据是否在指定的范围内。实际上,如果使用了Ran geVali dator、Com pareVali dator或者RegularExpressionValidator验证控件,数据输入控件为空会自动被成功验证,因为没有值需要验证。如果这不是你想要的结果,则可以给数据输入控件添加RequiredFieldValidator验证控件进行验证。这样就保证了两种类型的验证均被执行,并有效地约束了空值。

4.1.2 BaseValidator类

BaseValidator类位于System.Web.UI.WebControls命名空间中,是所有验证控件的抽象基类,如图4-1所示。

figure_0132_0094

图 4-1 验证控件类层次结构

BaseValidator类定义了验证控件的基本功能,为所有验证控件提供核心实现,它的常用属性与方法如表4-2所示。

figure_0133_0095

4.1.3 验证流程

在ASP.NET中,提供了许多能够回发到服务器的数据提交控件,如BulletedList、Button、CheckBox、CheckBoxList、DropDownList、HtmlButton、HtmlInputButton、HtmlInputImage、ImageButton、LinkButton、ListBox、RadioButtonList和TextBox控件。这些按钮都有一个CausesValidation属性,该属性可以设置为true和false。当用单点击上面的数据提交按钮时所发生的事情取决于CausesValidation属性的值。

❑如果CausesValidation属性设置为false, ASP.NET忽略验证控件,页面被回送,事件处理代码正常运行。

❑如果CausesValidation属性设置为true(默认为true),ASP.NET在用户单击上面的数据提交按钮时会自动检验页面是通过对页面的每个控件进行检验来实现的。控件检验失败时,根据你的设置,ASP.NET会返回一个错误信息页面。

值得注意的是,必须将控件的AutoPostBack属性设置为true时才回发到服务器。这些控件都有一个ValidationGroup属性,设置此属性后,当控件触发服务器回发时,仅验证指定组中的验证控件。若要将验证控件分组,请将每个验证控件的ValidationGroup属性设置为相同的值。

如表4-2所示,如果需要将输入控件与验证控件关联起来,请使用ControlToValidate属性;如果需要指定在验证失败时验证控件中显示的文本,请使用Text属性。当然,还可以使用ValidationSummary控件来显示页面中所有验证失败的控件的摘要。若要指定ValidationSummary控件中显示的文本,请使用ErrorMessage属性。如果设置了ErrorMessage属性但没有设置Text属性,则验证控件中也将显示ErrorMessage属性的值。

在使用验证程序控件时,应该始终首先检查服务器端验证的结果,然后再执行处理。在回发之后与调用事件方法之前,该页将调用验证程序控件并将它们的结果聚集到Page.IsValid属性中。(还可以使用Validate方法显式调用验证程序控件。)在自己的代码中,应该先检查Page.IsValid属性是否返回了true,然后再处理输入。即使支持脚本的浏览器可能在验证检查失败时禁止客户端上发生回发,也应该总是先检查服务器代码中的Page.IsValid,然后再处理验证的数据。还可以手动执行验证。若要验证页面上的所有验证控件,请使用Page.Validate方法。通过使用控件的Validate方法可以验证个别的验证控件。

注意 如果使用Page_Load方法中的Page.IsValid属性,则必须首先显式调用Page.Validate方法。因为验证在页面的Control.Load事件后与在Click或Command事件的事件处理程序前发生,所以直到调用Page.Validate方法后才会更新Page.IsValid属性。或者,可以将代码置于Click或Command事件的事件处理程序中,而不是置于Page_Load方法中。

最后,并非所有的数据输入控件都支持验证控件。可以用验证控件进行验证的标准控件包括DropDownList、FileUpload、ListBox、RadioButtonList、TextBox、HtmlInputFile、HtmlInputPassword、HtmlInputText、HtmlSelect和HtmlTextArea控件。