职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 1126|回复: 0

ASP.NET 2.0服务器控件之验证控件示例

[复制链接]
joe 发表于 2007-1-25 14:40 | 显示全部楼层 |阅读模式
  为了帮助读者更好的理解验证控件的实现方法,本文将首先介绍常见验证控件的实现步骤,然后,通过一个典型示例说明验证控件的实现方法。
  1. 验证控件实现步骤
  在创建验证控件过程中,需要实现服务器端验证和客户端验证等核心内容。下面列举了验证控件的常见实现步骤。
  (1)验证控件类应由BaseValidator基类继承。这样可使验证控件自动继承参与验证框架所需要的功能。例如,通过继承BaseValidator的ControlToValidate属性,实现验证控件与验证目标控件的关联。
  (2)实现验证控件所特有的一些属性。开发人员可根据应用需求,从方便实用的角度出发定义这些特有属性。
  (3)重写AddAttributesToRender方法,将特有属性及相关内容添加到控件呈现中。当实现客户端验证代码时可能需要引用相关呈现内容。
  (4)重写EvaluateIsValid方法,为验证控件添加服务器端验证逻辑。
  (5)重写PreRender事件的事件处理方法OnPreRender,除调用基类实现方法外,还要实现对客户端验证脚本文件的注册。
  (6)编写与验证控件一起打包的客户端验证脚本文件,并且将其放置到正确的目录中。
  通过以上的一个或者几个步骤,开发人员就可以实现一个基本的验证控件。在实现过程中,服务器端验证逻辑和客户端验证逻辑必须保持一致,否则,即使输入数据通过了客户端验证,也无法通过服务器端验证。下面将通过一个典型实例来进一步说明验证控件的实现方法,以加深读者的理解。
  2、典型应用
  本节将使用上文所介绍的开发验证控件的方法,创建一个名为TelNumValidator的验证控件。该控件用于验证用户输入的电话号码是否符合规则。如果不符合规则,那么动态提示错误信息。其效果如图1。

图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;
 }
}
  从以上代码可知,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文件中。这种实现方法非常有利于控件的部署工作。有兴趣的读者可以试一试。
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-11 01:46 , Processed in 0.136471 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表