扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
图1 效果图(输入错误状态下)
如图1所示,页面中主要包括了一个TextBox文本框和一个提交按钮。用户必须输入正确格式的电话号码,才能够通过验证。图1中,由于没有输入正确的电话号码,当单击提交按钮时,则无法实现提交页面。同时,页面还分红蓝两种颜色给出了提示信息。下文详细讲解了验证控件的实现过程。
首先,在实现TelNumValidator控件之前,必须进一步明确验证条件。
对于国内电话号码,一般为两种模式:一种是区号为3位,电话号码为8位,另一种是区号为4位,电话号码为7位。据此,可得出用于验证的正则表达式:“\d{3}-\d{8}|\d{4}-\d{7}”。无论是服务器端验证逻辑,还是客户端验证逻辑,都必须遵从以上验证条件。只有符合这两种模式的输入数据才能够通过验证。
下面列出了验证控件TelNumValidator的服务器端验证的源代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
namespace WebControlLibrary
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:TelNumValidator runat=server>
</{0}:TelNumValidator>")
]
public class TelNumValidator : BaseValidator
{
// 定义私有变量,其中_clientFileUrl表示JavaScript文件存储目录
// ValidationExpression表示正则表达式
private string _clientFileUrl = "ClientFiles/";
private const string ValidationExpression = @"(\d{3}-\d{8}|\d{4}-\d{7})";
// 定义属性ClientFileUrl,用于获取或设置脚本相对路径
[
Description("获取或设置脚本相对路径"),
DefaultValue("ClientFiles/"),
Category("Appearance")
]
public string ClientFileUrl
{
get
{ return _clientFileUrl; }
set
{ _clientFileUrl = value; }
}
//重写AddAttributesToRender,为验证控件添加特殊属性evaluationfunction和validationexp
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (RenderUplevel)
{
writer.AddAttribute("evaluationfunction", "TelNumValidatorEvaluateIsValid", false);
writer.AddAttribute("validationexp", ValidationExpression);
}
}
//重写EvaluateIsValid方法,定义服务器端验证逻辑
protected override bool EvaluateIsValid()
string controlValue = GetControlValidationValue(ControlToValidate);
if (controlValue == null)
{
return true;
}
controlValue = controlValue.Trim();
try
{
Match m = Regex.Match(controlValue, ValidationExpression);
return (m.Success && (m.Index == 0) && (m.Length == controlValue.Length));
}
catch
{
return false;
}
}
//重写OnPreRender方法,注册客户端脚本程序
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (RenderUplevel)
{Page.ClientScript.ReGISterClientScriptBlock ( typeof(TelNumValidator),
"ClientValidator", GetClientFileUrl ( "ClientValidator.js" ));
}
}
// 实现辅助函数GetClientFileUrl,用于获取JavaScript文件的完整路径
private string GetClientFileUrl(string fileName)
{
string tempClient = String.Format("<script language=\"javascript\" src=\"{0}\"></script>", (ClientFileUrl + fileName));
return tempClient;
}
}
[NextPage]
从以上代码可知,TelNumValidator控件的实现,是按照上文说明的验证控件实现步骤编写的。该类实现了以下重要逻辑:
(1)验证控件类TelNumValidator类从BaseValidator基类继承,因此,该类自动继承了通用验证控件应该具备的属性、方法和事件。
(2)定义用于获取或设置脚本相对路径的属性ClientFileUrl,默认值为“ClientFiles/”。通过该属性页面开发者可自定义客户端验证脚本文件的目录,这样可增加控件的灵活性。
(3)重写AddAttributesToRender方法,为控件添加特性evaluationfunction和validationexp。特性evaluationfunction对应的值是进行客户端验证的方法名。特性validationexp对应的值是用于验证的正则表达式,通过将其呈现到客户端,那么客户端验证脚本即可使用该表达式。
(4)重写EvaluateIsValid方法,定义服务器端验证逻辑。
(5)重写OnPreRender方法,注册客户端脚本文件ClientValidator.js。
读者可能已经注意到该验证控件需要实现客户端验证,而客户端验证包含在ClientValidator.js文件中。默认情况下,该文件位于“ClientFiles”文件夹中。
下面列出客户端验证文件ClientValidator.js的源代码。
function TelNumValidatorEvaluateIsValid(val)
{
var validationexp = val.validationexp;
var valueToValidate = ValidateTrim(ValidateGetValue(val.controltovalidate));
var rx = new RegExp(validationexp);
var matches = rx.exec(valueToValidate);
return (matches != null && valueToValidate == matches[0]);
}
/* 获取验证目标控件的输入数据 */
function ValidateGetValue(id)
{
var control;
control = document.all[id];
if (typeof(control.value) == "string")
{
return control.value;
}
if (typeof(control.tagName) == "undefined" && typeof(control.length) == "number")
{
var j;
for (j=0; j < control.length; j++)
{
var inner = control[j];
if (typeof(inner.value) == "string" && (inner.type != "radio" || inner.status == true))
{
return inner.value;
}
}
}
else
{
return ValidatorGetValueRecursive(control);
}
return "";
}
/* 去除空格处理 */
function ValidateTrim(s)
{
var m = s.match(/^\s*(\S+(\s+\S+)*)\s*$/);
return (m == null) ? "" : m[1];
}
由上代码可知,ClientValidatior.js文件中仅包括一个主方法TelNumValidatorEvaluateIsValid。该方法实现了与服务器端验证中,EvaluateIsValid方法相同的逻辑。同时,还包括两个辅助方法ValidateGetValue和ValidateTrim。前者用于获取验证目标控件的输入数据,后者用于去除空格处理。
为了测试当前自定义验证控件,下面列举了Default.ASPx页面源代码。
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ ReGISter TagPrefix="Sample" Assembly="WebControlLibrary" Namespace="WebControlLibrary" %>
<!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>
</head>
<body>
<form id="form1" runat="server">
<div style="font-size: small;">
<asp:TextBox ID="textbox" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="提交"></asp:Button>
<Sample:TelNumValidator ID="demo1" runat="server" Display="dynamic" ControlToValidate="textbox" Text="请输入有效的电话号码" ErrorMessage="正确的格式为010-12345678或者0123-1234567"></Sample:TelNumValidator>
<br /><br />
<asp:ValidationSummary runat="server" ForeColor="blue" DisplayMode="singleParagraph" HeaderText="错误信息:" ID="ValidationSummary1"></asp:ValidationSummary>
</div>
</form>
</body>
</html>
在以上实现中,请读者重点关注自定义验证控件的属性设置。该控件主要设置了以下几个重要属性。
(1)ControlToValidate属性,通过设置该属性,从而实现了验证控件TelNumValidator和验证目标控件TextBox之间的关联。
(2)Display属性,通过设置该属性可设置错误信息显示方式。
(3)ErrorMessage,该属性用于获取或设置验证失败时ValidationSummary控件中显示的错误信息的文本。为此,在代码中还设置了一个对应的ValidationSummary控件。
(4)Text,该属性用于获取或设置验证失败时验证控件中显示的文本。
需要注意的是以上4个属性都继承自BaseValidator基类。另外,如果应用程序部署需要,开发人员还可以修改验证控件的ClientFileUrl属性。
3. 小结
本文通过一个典型示例说明了验证控件的实现方法。相信读者已经能够感到,如果实现高质量的验证控件,开发人员必须掌握多方面的知识,尤其是JavaScript语言等。另外,本文所涉及的JavaScript代码被包含在js文件中。开发人员也可以将这些代码作为资源文件编译到验证控件的dll文件中。这种实现方法非常有利于控件的部署工作。有兴趣的读者可以试一试。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者