【翻译】多域校验控件——基于ASP.NET的验证控件[Carol]
多域校验控件——基于ASP.NET的验证控件
原文地址:http://www.codeproject.com/aspnet/MultipleFieldsValidator.asp
作者:Adam Tibi 翻译: Carol
我们探讨的是多域的校验,是指校验一组域,其中至少有一个域是必须被检验的,如电话号码,手机号或者电子邮件。它继承自BaseValidator并且使用了一些又新又炫的ASP.NET2.0特性。
导言
在理想世界中,网页使用者无需认证,因为他们是值得信赖的,那里将不会有千年虫或者任何不可预期的行为,所以也不用try-catch。使用者将提交有效的输入,因此你也无需使用网页校验。但是既然我们不是生活在那样的世界中,我希望一段时间后你们会发现这种校验是有用的。
在ASP.NET开发过程中,我遇到过许多案例:在许多备选域中你只需填充一个域。在这些域中进行校验,我曾习惯于用自定义校验,或者客户端脚本,或者有时只用服务器端验证。
使用自定义校验以及所有其他ASP.NET校验的问题在于:它们主要用于处理一个或两个域,而且每次遇到校验多个域时,你都需要写自定义的服务器端或客户服务器端代码,或者也许就是复制和粘贴代码。为了解决这一问题,我制作了这个轻量级的多控件的校验控件,并且使用了新的ASP.NET 2.0特性。
背景
即使使用ASP.NET 2.0,许多珍贵的校验控件都在丢失,尤其是那些用于多域的校验。Peter Blum创造了一套叫做Professional Validation And More(专业校验及更多)的商业控件来填补这一缺口。他在回答我的论坛的帖子时,给了我实践自己的校验控件的想法。
在CodeProject上我也发现了一些由Daniel Hacquebord著的关于CustomValidator dependent on multiple controls(基于多控件的定制校验控件)的好文章。它提出了一种同样的需要。这种校验控件具备以下几个优势:
1. 不需要写任何客户端或服务端代码。只需将它拖到页面上然后指定你想校验的控件。
2. HTML/XHTML兼容。它用JavaScript指定附加属性,而不是将附加属性直接添加到span标签。也就是说,它使用JavaScript
document["MyMultipleFieldsValidator"].condition = "OR"
而不是 HTML <span id="MyMultipleFieldsValidator" condition = "OR">.
3. 使用.js资源档案来注册客户端代码,而不用在每一张需要这一控件的页面上写客户代码。
4. 直接从BaseValidator继承下来,相对于从 CusomValidator继承得到了一些细小的额外特性
在CodeProject上还有一篇好文章给了我一些启示,文章的题目是RequiredIfValidator - Extending from the BaseValidator class,是关于一种校验控件,用于校验基于下拉列表选择的另一个项。
使用代码
这个控件基于的BaseValidator,主要用于处理一个控件,所以我不得不禁用一些旨在校验一个单独控件的属性。我得把ControlToValidate 和SetFocusOnError属性覆盖,并把它们从设计者及Visual Studio编辑者那隐藏起来。
[EditorBrowsable(EditorBrowsableState.Never)]
public new bool SetFocusOnError {
get {
return false;
}
set {
throw new NotSupportedException("SetFocusOnError is not supported.");
}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new string ControlToValidate {
get {
return string.Empty;
}
set {
throw new NotSupportedException("ControlToValidate is not supported.");
}
}
在AddAttributesToRender方法中我使用ASP.net 2.0提供的RegisterExpandoAttribute方法动态的将调用JavaScript的语句添加到由validator生成的<span>标签中而不是静态的写入页面这样可以保持HTML/XHTML代码的友好度
string clientID = this.ClientID;
Page.ClientScript.RegisterExpandoAttribute(clientID,
"evaluationfunction",
"MultipleFieldsValidatorEvaluateIsValid");
Page.ClientScript.RegisterExpandoAttribute(clientID,
"controlstovalidate",
this.GenerateClientSideControlsToValidate());
Page.ClientScript.RegisterExpandoAttribute(clientID,
"condition",
PropertyConverter.EnumToString(typeof(Conditions), Condition));
}
在OnPreRender,我已经使用了新的ASP.NET 2.0方法:RegisterClientScriptResource,用以将我的嵌入的.js档案添加到页面。在CodeProject 上有一篇名为WebResource ASP.NET 2.0 explained的好文章是用于处理这一问题的,其作者是Gary Dryden。
base.OnPreRender(e);
if (base.RenderUplevel) {
this.Page.ClientScript.RegisterClientScriptResource(
typeof(MultipleFieldsValidator),
"AdamTibi.Web.UI.Validators.WebUIValidationExtended.js");
}
}
使用校验控件
要从你的Visual Studio IDE中使用这一校验,你需要把提供的.dll添加到工具箱。关于这一点更多的信息,请点击MSDN documentation。
在web form 上拖一个校验控件之后,你所需做的只要设置ControlsToValidate属性,在属性窗口上指出你想校验的控件。本文附带的演示有更多的例子。
默认状态下会被设置为OR的Condition属性设定了你校验多域时所要运用的条件。因此,OR确保其中一个域是需要被填写的,而XOR确保其中之一被检验而不是全部。
<%@ Register TagPrefix="atv" Namespace="AdamTibi.Web.UI.Validators"
Assembly="AdamTibi.Web.UI.Validators" %>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="txtPhone" runat="server"></asp:TextBox>
<asp:TextBox ID="txtMobile" runat="server"></asp:TextBox>
<asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
<atv:MultipleFieldsValidator ID="mfv" runat="server" Condition="OR"
ControlsToValidate="txtPhone,txtMobile,txtEmail">
fill at least one field</atv:MultipleFieldsValidator>
</form>
</body>
</html>
局限
我只在IE6和Firefox1.5上试验过此种校验,但我没有使用任何怪异的JavaScript,所以它也应该可以在其他浏览器上作用。如果你使用成功,请告知。
我只需要它来校验文本框领域,所以我没有使用其他类型的控件。但理论上说,它应该是有效的。如果你遇到任何问题也请告知。
结论
希望能令你一天都开心。如果喜欢这个文章请记得投票。如果有任何建议,故障或者提高请联系我。
路漫漫其修远兮 吾将上下而求索
my blog