日期:2009-11-25  浏览次数:20452 次

有效性规则和有用的错误信息

每个验证器会显示有关特定控件特定情况的特定错误信息。其中有一些确认是否有效的规则,开始,您作为一个开发人员可能会有些混淆,但是如果要生成对用户有实际帮助的错误信息,这些规则是必要的。

所有空的验证器(除了 RequiredFieldValidator)均会被认为有效。如果某个空值无效,您通常需要一个 RequiredFieldValidator 和一个其它验证器。您需要这样做,因为一般情况下,您总是希望对空验证器和有效性显示不同的错误信息。您也可以使用不明确的信息,例如“您必须输入一个值,并且该值必须在 1 和 10 之间”。

在输入字段无法转换为指定数据类型时使用的另一个特殊规则与 CompareValidator 和 RangeValidator 有关。对指定了 ControlToCompare 的 CompareValidator 进行的有效性评估过程类似如下所述:

如果 ControlToValidate 引用的输入字段为空,则有效。
如果 ControlToValidate 引用的输入字段无法转换成所需数据类型,则无效。
如果 ControlToCompare 引用的输入字段无法转换成所需数据类型,则有效。
输入字段转换成所需数据类型并进行比较。
第三步看起来有些不符合直觉。之所以这样评估,是因为如果验证器同时检查多个字段的有效性,很难为该验证器写出有意义的错误信息。应使用一个独立的验证器来报告 ControlToCompare 输入字段中的错误情况。RangeValidator 的工作方式类似,具有 maximum 和 minimum 属性。


Enabled、Visible 和 Display 属性的作用

验证器的 Enabled、Visible 和 Display 属性之间的区别可能不是非常明显。

Display=None 可以用来指定验证器不直接显示任何内容,但是仍然进行评估,仍然影响总体的有效性,并且仍可以将错误放在客户机和服务器上的摘要中。对于客户端验证,这些值确定使用可见性样式特性还是使用显示样式特性来打开或关闭验证器。对于服务器端验证,Display=Dynamic 表示输入有效时不显示任何内容,而 Display=Static 表示显示一个不换行的空格 (" ")。使用最后一个设置是为了表中只包含验证器的单元格在有效时,不会折叠成不显示任何内容。

为什么不只使用 Visible=false 使验证器不可见呢?在 ASP+ 中,控件的 Visible 属性有许多含义:Visible=false 的控件根本不会被处理来预显示或显示。正是因为这种含义,验证器的 Visible=false 意味着不仅不会显示任何内容,而且无法使用。不会对这样的验证器进行评估,不会影响页面的有效性,也不会将错误放在摘要中。

Enabled 则为中性。对于大多数情况,Enabled=false 与 Visible=false 的效果完全相同。在 Beta 1 版或更高版本中,存在一个重要的区别:在客户端验证中,禁用的验证器仍会发送到浏览器中,但是处于禁用状态。您可以使用客户端脚本中的 ValidatorEnable 函数激活该验证器。

使用 Visible 或 Enabled 控制是否进行验证时,应注意上述服务器上的事件顺序。或者在验证之前进行更改,或者在更改之后重新验证。否则,它们的 IsValid 值不会将更改反映到属性上。


CustomValidator 控件

扩展验证框架最简单的方法是使用 CustomValidator 控件。该控件既可以用来执行其它验证控件无法进行的验证,也可以执行需要访问服务器上信息(例如数据库或 Web 服务)的验证。

如果添加了只定义一个服务器验证函数的 CustomValidator,您会注意到,该验证器并不参与客户端验证。当用户使用 tab 键在各字段之间切换时,CustomValidator 不会更新,并且需要往返服务器一次以执行其验证。如果要使用 CustomValidator 执行不需要任何服务器上信息的检查,您也可以使用 ClientValidationFunction 属性让验证器完全参与客户端验证。假设您提供了一个 ClientValidationFunction,理想情况下,应与服务器验证处理程序执行完全相同的检查。但实际上,只是执行该验证的一部分。客户端验证函数进行的验证不要超过在服务器上执行的验证,因为黑客很容易绕过该验证函数。

以下是在客户机和服务器上使用 CustomValidator 的一个简单示例,只检查输入是否是偶数。以下先介绍服务器函数(在 C# 中):

public bool ServerValidation(object source, string value) {
try {
int i = int.FromString(value);
return ((i % 2) == 0);
} catch {
return false;
}
}

以下是该函数在客户机上的声明方法,以及一个执行相同检查的客户端验证函数。这通常是 JScript 形式,不过如果您的目标是 Microsoft® Internet Explorer,也可以使用 VBScript® 形式。

<ASP:CustomValidator id="customVal2" runat=server
ErrorMessage="数字不可以被 2 除!"
ControlToValidate="txtCustomData"
OnServerValidationFunction=ServerValidation
ClientValidationFunction="CheckEven" /><br>
Data Field : <ASP:TextBox id="txtCustomData" runat="server" />
<script language=JavaScript>
<!--
function CheckEven(source, value) {
var val = parseInt(value, 10);
if (isNaN(val))
return false;
return ((val % 2) == 0);
}
// -->
</script>

以下是使用 CustomValidator 的一些注意事项:

与所有其它验证控件类似(RequiredFieldValidator 除外),如果输入字段为空,则认为 CustomValidator 有效。
如果使用较旧的浏览器,或者关闭了客户端验证,将无法调用客户端验证函数。在定义该函数之前,您不必检查所用浏览器的功能,但是需要确保浏览器不会因为定义而造成脚本错误。一定要使您的客户端代码作为 HTML 注释,如下例所示。
两个参数传递到您的客户端函数中,与传递给服务器函数的参数对应。第一个是客户端验证器元素,第二个是 ControlToValidate 指定的控件值。不过,在客户机上,您可以选择不为函数定义参数,这样也会正常工作。
如果使用 Beta1 版或更高版本,您可以保留 ControlToValidate 为空。在该模式中,服务器函数每次往返总会触发一次,客户端函数每次尝试提交时总会触发一次。您可以使用该特性来验证其它方法无法验证的控件,例如 CheckBoxList 或单独的单选按钮。如果条件是基于多个控件,并且您不希望用户使用 tab 键在页面上各字段之间切换时评估该条件,可以使用该方法。
Beta 1 版或更高版本中的另一个选项是挂接多个控件的 change 事件。方法是加入一些调用客户端函数 ValidatorHookupControl 的内嵌脚本,如上所述。

哪些控件可以被验证?

要使控件可以被验证控件引用,该控件必须具有验证属性。所有可以验证的控件均具有 ValidationPropertyAttribute 属性,该属性指明验证时应读取的属性。如果编写自己的控件,可以通过提供其中一个特性来指定要使用的属性,从而使该控件参与验证。

要使验证可以在客户端正常进行,该属性必须与客户端显示的 HTML 元素的 value 特性对应。许多复杂的控件(例如 DataGrid 和 Calendar)在客户端没有值,只能在服务器上进