发一个2004年年初写的验证控件文章
开发自定义.net验证控件(原创)
author: 丁科康(kkding)
前言:本文的面向对象是.net开发者,必须具备以下知识。
ü C#的基本知识;
ü 开发过.net的Web自定义控件;
ü 丰富的javascript脚本开发能力;
ü 熟悉正则表达式。
大家在做.net Web应用程序的时候经常碰到客户输入的数据需要大量的验证,如果验证工具交给服务器去验证的话,无疑是增加服务器的压力,而且也容易造成程序的异常;如果使用微软的验证控件的话,总觉得不方便,而且有的验证数据是无法去自定义,并且假如一个输入框要验证多个条件的话,必须拖动多个验证控件,比如:输入数据不能为空,要求是10位长度的Integer数据类型,开发者就必须拖动RequiredFieldValidator和CompareValidator 等验证控件,但是无法限制数据长度,等等。总是达不到你验证的数据要求,或者不能合成,一个数据验证需要多个验证控件去验证。
看一下现在的大多数商业网站,您会注意到它们充满了大量的表单,而且都是通过手写的javascript代码进行验证。编写验证代码确实不是件很容易的事情。Web应用程序的验证尤其困难。本文先介绍微软的验证控件是如何运作原理,如何提取信息,然后是介绍我们该如何的去写自己的验证控件。
我们以RequiredFieldValidator 控件为例:
可以看到RequiredFieldValidator 控件在开发环境中的表达示如下。
图- 1
<asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
ErrorMessage="请输入数据" ControlToValidate="txtid">
</asp:RequiredFieldValidator>
我们可以在访问有验证控件的页面中点右键”查看源文件”,下面代码是显示控件呈现后在页面的代码。
<span id="RequiredFieldValidator1" controltovalidate="txtid" errormessage="请输入数据" evaluationfunction="RequiredFieldValidatorEvaluateIsValid" initialvalue="" style="color:Red;visibility:hidden;">请输入数据</span>
脚本代码
<script language="javascript">
<!--
var Page_Validators = new Array(document.all["RequiredFieldValidator1"]);
// -->
</script>
<script language="javascript">
<!--
var Page_ValidationActive = false;
if (typeof(clientInformation) != "undefined" && clientInformation.appName.indexOf("Explorer") != -1) {
if (typeof(Page_ValidationVer) == "undefined")
alert("无法找到脚本库“/aspnet_client/system_web/1_1_4322/WebUIValidation.js”。请尝试手动放置此文件,或通过运行“aspnet_regiis -c”重新安装。");
else if (Page_ValidationVer != "125")
alert("此页使用了 WebUIValidation.js 的错误版本。此页应该使用版本 125。脚本库为 " + Page_ValidationVer + "。");
else
ValidatorOnLoad();
}
function ValidatorOnSubmit() {
if (Page_ValidationActive) {
ValidatorCommonOnSubmit();
}
}
// -->
</script>
每个按钮都有个”CausesValidation”属性,我们可以在HTML代码中找到这段代码
<input type="submit" name="Button1" value="OK" onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " language="javascript" id="Button1" />
我们可以看到当用户激活验证的时候是在提交中的onclick事件中激活。在页面载入的时候,微软把要验证的表单对象放在RequiredFieldValidator控件的controltovalidate属性中,然后把验证控件的数据放在Page_Validators对象中,如:
var Page_Validators = new Array(document.all["RequiredFieldValidator1"]);
如果有多个数据要验证,则存储在Page_Validators (Array对象中)中。当激活的时候,调用Page_ClientValidate()脚本函数,我们可以在/aspnet_client/system_web/1_1_4322/ WebUIValidation.js中找到这个脚本。让我们来分析WebUIValidation.js这个脚本文件。
先从Page_ClientValidate 入手
图- 2
可以看到ValidatorValidate(Page_Validators[i])是验证Page_Validators (Array对象)中的数据。ValidatorUpdateIsValid是验证验证控件的有效性。
ValidationSummaryOnSubmit是显示微软控件ValidationSummary的消息。
再来看看ValidatorValidate函数
图- 3
图- 3红框中的代码是调用写在验证控件Html代码中的RequiredFieldValidatorEvaluateIsValid方法。ValidatorUpdateDisplay(val)是更新显示效果。
从上可以知道微软是把要验证的输入对象和验证方式、显示方式、消息等放在一个Span的HTML元素对象中,然后把对应的Span的ID注册到Page_Validators (Array对象)中,通过按钮的onclick事件激活Page_ClientValidate函数来验证数据。(由于按钮的是否验证属性是集成在按钮中,所以我们只能继续使用Page_ClientValidate这个验证入口函数)
这样我们已经知道微软的验证控件的原理了。
现在,我可以开始写自己的验证控件了。
首先,我们确定下我们要验证的范围,我们通常要验证的有字符、数字、浮点、Email、电话号码、日期、时间等,还要验证数据是否非空、数据的长度,还有验证的显示方式
(注:没有写命名空间的都是在DMWZ.UI.WebControls下)
1. 首先我们先定义我们要验证那些我们通常需要验证的数据类型和显示方式的枚举。
/// <summary>
/// 验证规则
/// </summary>
public enum ValidationDataType
{
/// <summary>
/// 空验证
/// </summary>
Empty = 0,
/// <summary>
/// 字符串
/// </summary>
String = 1,
/// <summary>
/// A-Z或a-z字母
/// </summary>
Letter =2,
/// <summary>
/// 规则字符
/// </summary>
StringInteger=3,
/// <summary>
/// 或带符号整型
/// </summary>
Integer = 4,
/// <summary>
/// 允许规则中文
/// </summary>
Chinese = 5,
/// <summary>
/// 无符号
/// </summary>
UnSignInteger = 6,
/// <summary>
/// 或符号小数
/// </summary>
Double = 7,
/// <summary>
/// Email
/// </summary>
Email = 8,
/// <summary>
/// IP地址
/// </summary>
IP = 9,
/// <summary>
/// 电话号码
/// </summary>
Phone =10,
/// <summary>
/// 邮政编码
/// </summary>
ZIP = 11,
/// <summary>
/// 货币美元和人民币
/// </summary>
Currency = 12,
/// <summary>
/// 日期
/// </summary>
Date = 13,
/// <summary>
/// 时间
/// </summary>
Time=14,
/// <summary>
/// 日期时间
/// </summary>
DateTime =15,
/// <summary>
/// 无符号小数
/// </summary>
UnSignDouble = 16,
/// <summary>
/// 其他
/// </summary>
Other= 17
}
/// <summary>
/// 消息显示方式
/// </summary>
public enum ValidatorDisplay
{
/// <summary>
/// 无
/// </summary>
None=0,
/// <summary>
/// 静态
/// </summary>
Static=1,
/// <summary>
/// 动态
/// </summary>
Dynamic=2,
/// <summary>
/// 警告
/// </summary>
Alert=3
}
2. 然后我们要写一个验证控件类(DMWZ.UI.WebControls.DataValidator),这个类通过System.Web.UI.WebControls.Label类扩展,接口IValidator。我们要在Label控件的基础上添加Display、DataType、ErrorMessage、AllowNull、ControlToValidate、MaxLength这些属性。当客户端解析aspx生成的Html代码时,通过Span元素,我们把上述属性填入到Span中,并在页面中注册这些验证对象,也就是在我们的Page_Validators (Array对象)。
按照代码的顺序,如下(类体、变量、属性、构造、方法):
Ø 类体
[ToolboxBitmap(typeof(System.Web.UI.WebControls.RequiredFieldValidator)),ToolboxDataAttribute("<{0}:DataValidator runat=server ErrorMessage=\"please input data.\"></{0}:DataValidator>")]
public class DataValidator : Label, IValidator
{
……
}
ToolboxBitmap(typeof(System.Web.UI.WebControls.RequiredFieldValidator))表示我们继续使用System.Web.UI.WebControls.RequiredFieldValidator类的图标。
Ø 变量
#region 变量
/// <summary>
/// 脚本文件位置
/// </summary>
private const string SCRIPTFILE="/js/Validator.js";
/// <summary>
/// 本地资源管理器,管理页面资源,要指向System.Web.Resource.dll
/// </summary>
private static ResourceManager _resourceManager;
/// <summary>
/// Http的进程
/// </summary>
private static HttpRuntime _theRuntime = new HttpRuntime();
private bool isValid;
/// <summary>
/// 属性检测
/// </summary>
private bool propertiesChecked;
/// <summary>
/// 属性是否有效
/// </summary>
private bool propertiesValid;
/// <summary>
/// 呈现级别
/// </summary>
private bool renderUplevel;
#endregion
Ø 属性
[……]中的意思如果具有写控件的知识应该能明白,这里我们简单的说下:Category是描述这个属性或事件的种类;DefaultValue是指这个属性的缺省值;Description是描述这个属性的意思,相当于备注; 另外,我们要重点提下TypeConvertAttribute,这是指定专门的(DMWZ.UI.WebControls.ValidateControlConverter)类转换数据,由于我们是验证输入框中的数据,因此我们要在页面的上下文中获取输入框(通常情况下都是TextBox控件)的ID值
#region 属性
/// <summary>
/// 指定验证的控件
/// </summary>
[Category("Behavior"),
DefaultValue(""),
Description("验证的控件"),
TypeConverterAttribute(typeof(DMWZ.UI.WebControls.ValidatedControlConverter))]
public string ControlToValidate
{
get
{
object local = base.ViewState["ControlToValidate"];
if (local != null)
{
return (String)local;
}
else
{
return String.Empty;
}
}
set
{
base.ViewState["ControlToValidate"] = value;
}
}
/// <summary>
/// 脚本是否有效
/// </summary>
[Category("Behavior")]
[Description("BaseValidator_EnableClientScript")]
[DefaultValue(true)]
public bool EnableClientScript
{
get
{
object local = base.ViewState["EnableClientScript"];
if (local != null)
{
return (bool)local;
}
else
{
return true;
}
}
set
{
base.ViewState["EnableClientScript"] = value;
}
}
/// <summary>
/// 是否验证为空
/// </summary>
[Bindable(true), Description("是否验证空."),
Category("Behavior"),
DefaultValue("true")]
public bool AllowNull
{
get
{
object local = base.ViewState["AllowNull"];
if (local != null)
{
return (bool)local;
}
else
{
return true;
}
}
set
{
base.ViewState["AllowNull"] = value;
}
}
/// <summary>
/// 验证数据的最大长度,0不验证
/// </summary>
[Bindable(true), Description("数据最大长度."),
Category("Behavior"),
DefaultValue("0")]
public int MaxLength
{
get
{
object local = base.ViewState["MaxLength"];
if (local != null)
{
int max=Convert.ToInt32( local);
return max<0?0:max;
}
else
{
return 0;
}
}
set
{
base.ViewState["MaxLength"] = value;
}
}
/// <summary>
/// 验证的错误信息
/// </summary>
[Description("验证的错误信息"),DefaultValue(""),
BindableAttribute(true),Category("Appearance")]
public string ErrorMessage
{
get
{
object local = base.ViewState["ErrorMessage"];
if (local != null)
{
return (String)local;
}
else
{
return String.Empty;
}
}
set
{
base.ViewState["ErrorMessage"] = value;
}
}
/// <summary>
/// 是否有效
/// </summary>
[BrowsableAttribute(false),DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
Category("Behavior"),DefaultValue(true),Description("BaseValidator_IsValid")]
public bool IsValid
{
get
{
return isValid;
}
set
{
isValid = value;
}
}
/// <summary>
/// 属性是否有效
/// </summary>
protected bool PropertiesValid
{
get
{
if (!propertiesChecked)
{
propertiesValid = ControlPropertiesValid();
propertiesChecked = true;
}
return propertiesValid;
}
}
/// <summary>
/// 呈现级别
/// </summary>
protected bool RenderUplevel
{
get
{
return renderUplevel;
}
}
/// <summary>
/// 验证数据类型
/// </summary>
[BindableAttribute(true)]
[DescriptionAttribute("验证规则")]
[DefaultValueAttribute(ValidatorDisplay.Static)]
[CategoryAttribute("Behavior")]
public DMWZ.UI.WebControls.ValidationDataType DataType
{
get
{
object local = base.ViewState["DataType"];
if (local != null)
{
return (DMWZ.UI.WebControls.ValidationDataType)local;
}
else
{
return DMWZ.UI.WebControls.ValidationDataType.String ;
}
}
set
{
if (value < DMWZ.UI.WebControls.ValidationDataType.Empty || value > DMWZ.UI.WebControls.ValidationDataType.Other)
{
throw new ArgumentOutOfRangeException("value");
}
base.ViewState["DataType"] = value;
}
}
/// <summary>
/// 显示方式
/// </summary>
[BindableAttribute(true)]
[DescriptionAttribute("显示方式")]
[DefaultValueAttribute(ValidatorDisplay.Alert)]
[CategoryAttribute("Appearance")]
public DMWZ.UI.WebControls.ValidatorDisplay Display
{
get
{
object local = base.ViewState["Display"];
if (local != null)
{
return (DMWZ.UI.WebControls.ValidatorDisplay)local;
}
else
{
return DMWZ.UI.WebControls.ValidatorDisplay.Alert ;
}
}
set
{
if (value < DMWZ.UI.WebControls.ValidatorDisplay.None || value > DMWZ.UI.WebControls.ValidatorDisplay.Alert)
{
throw new ArgumentOutOfRangeException("value");
}
base.ViewState["Display"] = value;
}
}
#endregion
Ø 构造 设置下缺省的变量和属性。
public DataValidator()
{
isValid = true;
propertiesChecked = false;
propertiesValid = true;
base.ForeColor = Color.Red;
}
Ø 方法
方法里我们主要实现下列功能:
1. 注册脚本,这里我把验证的js脚本放在资源文件中,当发现虚拟目录中没有此文件的时候,将此文件写入对应的位置。
2. 把我们定义的属性和属性值添加到Span中。
3. 在页面中声明验证的验证数组。
#region 方法
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
base.Page.Validators.Add(this);
}
protected override void OnUnload(EventArgs e)
{
if (base.Page != null)
{
base.Page.Validators.Remove(this);
}
base.OnUnload(e);
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
propertiesChecked = false;
renderUplevel = DetermineRenderUplevel();
if (renderUplevel)
{
RegisterValidatorCommonScript();
}
}
注册页面脚本
/// <summary>
/// 页面注册通用脚本
/// </summary>
protected void RegisterValidatorCommonScript()
{
if (base.Page.IsClientScriptBlockRegistered("ValidatorScript"))
{
return;
}
string spath=Page.Request.ApplicationPath;
if(spath.Equals("/")) spath="";
string strsrc="<script language=\"javascript\" src=\""+spath+SCRIPTFILE+"\"></script>";
spath=Page.Server.MapPath (Page.Request.ApplicationPath);
if(!File.Exists(spath+"\\js\\Validator.js"))
{
if(!Directory.Exists(spath+"\\JS"))
{
Directory.CreateDirectory(spath+"\\JS");
}
System.Text.Encoding encode=System.Text.Encoding.GetEncoding("Gb2312");
StreamWriter sw=new StreamWriter(spath+"\\JS\\Validator.js",false,encode);
sw.WriteLine(DMWZ.UI.Resources.ManagerResource.GetResourceContent("DMWZ.UI.Resources.JS.Validator.js",encode));
sw.Flush();
sw.Close();
}
base.Page.RegisterStartupScript("ValidatorScript", strsrc);
}
/// <summary>
/// 申明几个验证对象
/// </summary>
protected void RegisterValidatorDeclaration()
{
string str = String.Concat("document.all[\"", base.ClientID, "\"]");
base.Page.RegisterArrayDeclaration("Page_Validators", str);
}
/// <summary>
/// 呈现
/// </summary>
/// <param name="writer">输出流</param>
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
RegisterValidatorDeclaration();
}
protected bool DetermineRenderUplevel()
{
Page page = base.Page;
if (page == null || page.Request == null)
{
return false;
}
if (EnableClientScript && page.Request.Browser.MSDomVersion.Major >= 4)
{
return page.Request.Browser.EcmaScriptVersion.CompareTo(new Version(1, 2)) < 0 == false;
}
else
{
return false;
}
}
将我们定义的属性值添加到Span中
/// <summary>
/// 添加属性
/// </summary>
/// <param name="writer">输出对象</param>
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
bool flag = base.Enabled == false;
if (flag)
{
base.Enabled = true;
}
base.AddAttributesToRender(writer);
if (RenderUplevel)
{
if (base.ID == null)
{
writer.AddAttribute("id", base.ClientID);
}
if (ControlToValidate.Length > 0)
{
writer.AddAttribute("controltovalidate", GetControlRenderID(ControlToValidate));
}
if (ErrorMessage.Length > 0)
{
writer.AddAttribute("errormessage", ErrorMessage, true);
}
if (!IsValid)
{
writer.AddAttribute("isvalid", "False");
}
if (flag)
{
writer.AddAttribute("enabled", "False");
}
writer.AddAttribute("Display",Display.ToString());
writer.AddAttribute("MaxLength",MaxLength.ToString());
writer.AddAttribute("AllowNull",AllowNull.ToString());
writer.AddAttribute("DataType",DataType.ToString());
}
if (flag)
{
base.Enabled = false;
}
}
/// <summary>
/// 获取控件对象
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
protected string GetControlRenderID(string name)
{
Control control = base.FindControl(name);
if (control == null)
{
return "";
}
else
{
return control.ClientID;
}
}
/// <summary>
/// 是否验证
/// </summary>
public void Validate()
{
if (!base.Visible || !base.Enabled)
{
IsValid = true;
return;
}
for (Control control = base.Parent; control != null; control = control.Parent)
{
if (!control.Visible)
{
IsValid = true;
return;
}
}
propertiesChecked = false;
if (!PropertiesValid)
{
IsValid = true;
return;
}
IsValid = EvaluateIsValid();
}
protected virtual bool ControlPropertiesValid()
{
string str = ControlToValidate;
if (str.Length == 0)
{
throw new HttpException(FormatResourceString("Validator_control_blank", base.ID));
}
CheckControlValidationProperty(str, "ControlToValidate");
return true;
}
protected void CheckControlValidationProperty(string name, string propertyName)
{
Control control = base.NamingContainer.FindControl(name);
if (control == null)
{
throw new HttpException(FormatResourceString("Validator_control_not_found", name, propertyName, base.ID));
}
if (GetValidationProperty(control) == null)
{
throw new HttpException(FormatResourceString("Validator_bad_control_type", name, propertyName, base.ID));
}
else
{
return;
}
}
public static PropertyDescriptor GetValidationProperty(object component)
{
ValidationPropertyAttribute validationPropertyAttribute = (ValidationPropertyAttribute)TypeDescriptor.GetAttributes(component)[typeof(ValidationPropertyAttribute)];
if (validationPropertyAttribute != null && validationPropertyAttribute.Name != null)
{
return TypeDescriptor.GetProperties(component, null)[validationPropertyAttribute.Name];
}
else
{
return null;
}
}
/// <summary>
/// 获取资源
/// </summary>
/// <param name="key">关键字</param>
/// <returns>结果字串</returns>
private static string GetResourceString(string key)
{
if (_resourceManager == null)
{
HttpRuntime httpRuntime;
System.Threading.Monitor.Enter(httpRuntime = _theRuntime);
try
{
if (_resourceManager == null)
{
_resourceManager = new ResourceManager("System.Web", typeof(HttpRuntime).Module.Assembly);
}
}
finally
{
System.Threading.Monitor.Exit(httpRuntime);
}
}
return _resourceManager.GetString(key, null);
}
protected bool EvaluateIsValid()
{
return true;
}
internal static string FormatResourceString(string key)
{
return GetResourceString(key);
}
internal static string FormatResourceString(string key, string arg0)
{
string str = GetResourceString(key);
if (str == null)
{
return null;
}
else
{
return String.Format(str, arg0);
}
}
internal static string FormatResourceString(string key, string arg0, string arg1)
{
string str = GetResourceString(key);
if (str == null)
{
return null;
}
else
{
return String.Format(str, arg0, arg1);
}
}
internal static string FormatResourceString(string key, string arg0, string arg1, string arg2)
{
string str = GetResourceString(key);
if (str == null)
{
return null;
}
else
{
return String.Format(str, arg0, arg1, arg2);
}
}
internal static string FormatResourceString(string key, string[] args)
{
string str = GetResourceString(key);
if (str == null)
{
return null;
}
else
{
return String.Format(str, args);
}
}
#endregion
3. 定义从查找页面查找要验证数据的控件的类。此类是实现在页面中验证控件属性中查找需要验证的TextBox的一个集合。
public class ValidatedControlConverter : StringConverter
{
private object[] GetControls(IContainer container)
{
ComponentCollection componentCollection = container.Components;
ArrayList arrayList = new ArrayList();
IEnumerator iEnumerator = componentCollection.GetEnumerator();
try
{
while (iEnumerator.MoveNext())
{
IComponent iComponent = (IComponent)iEnumerator.Current;
if (iComponent is Control)
{
Control control = (Control)iComponent;
if (control.ID != null && control.ID.Length != 0)
{
ValidationPropertyAttribute validationPropertyAttribute = (ValidationPropertyAttribute)TypeDescriptor.GetAttributes(control)[typeof(ValidationPropertyAttribute)];
if (validationPropertyAttribute != null && validationPropertyAttribute.Name != null)
{
arrayList.Add(String.Copy(control.ID));
}
}
}
}
}
finally
{
if(iEnumerator is IDisposable)
{
IDisposable iDisposable = (IDisposable)iEnumerator;
if (iDisposable != null)
{
iDisposable.Dispose();
}
}
}
arrayList.Sort(Comparer.Default);
return arrayList.ToArray();
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
if (context == null || context.Container == null)
{
return null;
}
object[] locals = GetControls(context.Container);
if (locals != null)
{
return new StandardValuesCollection(locals);
}
else
{
return null;
}
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
}
4. 现在我们要写资源文件,把验证的资源脚本写在dll中(本人把所有资源写在DMWZ.UI.Resources.dll文件中),当Web应用程序中这个脚本不存在时,会把这个脚本文件写入到应用程序的js目录中。
因此,我们先定义一个载入资源管理的类ManagerResource。
#region 方法
/// <summary>
/// 获取资源
/// </summary>
/// <param name="resourceID">资源名字空间</param>
/// <returns>脚本</returns>
public static string GetResourceContent(string resourceID,System.Text.Encoding encode)
{
Stream stream;
stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceID);
StreamReader sr = new StreamReader(stream,encode);
string s=sr.ReadToEnd();
sr.Close();
return s;
}
#endregion
5. 把验证的资源文件Validator.js放入到程序集中DMWZ.UI.Resources.JS.Validator.js嵌入资源中。首先我们参照微软的验证脚本,声明个入口函数Page_ClientValidate()。
function Page_ClientValidate()
{
var i;
for (i = 0; i < Page_Validators.length; i++) {
if(!ValidatorValidate(Page_Validators[i]))
{
MsgBox(Page_Validators[i]);
event.returnValue = false;
return false;
}
}
}
我们可以通过Page_Validators对象可以验证我们所需要的验证的数据。以下是我的思路:
先循环获取验证信息,即我们在页面上放置的验证控件,然后就可以得到对应的验证对象等我们所需的信息,通过正则表达示去验证我们所需判断的类型是不是适合我们所需要的类型。
以下是我的验证脚本
function MsgBox(val)
{
if(Msg!="")
{
Msg="(错误提示:"+Msg+")";
}
if(val.Display=="Alert")
{
alert(ValidatorErrorMsg(val)+"\r\n"+Msg);
}
else if(val.Display=="Static")
{
val.innerHTML=ValidatorErrorMsg(val)+Msg;
}
else if (val.Display=="Dynamic")
{
val.innerHTML=ValidatorErrorMsg(val)+Msg;
control = ValidatorControl(val.controltovalidate);
return;
}
}
///单个验证
function ValidatorValidate(val) {
var control = ValidatorControl(val.controltovalidate);
value=ValidatorGetValue(control);
if(!MaxLength(val.MaxLength,value)) return false;
flag=true;
if(value=="")
{
control.focus();
Msg="文本框不能为空!";
return val.AllowNull=="True";
}
var dataType = val.DataType;
if(dataType=="Empty")
{
flag= true;
}
else if(dataType =="String")
{
flag = IsString(value);
}
else if(dataType =="Letter")
{
flag = IsLetter(value);
}
……
if(flag==false)
{
control.focus();
}
return flag;
}
function IsInteger(val)
{
reg=/^[-+]?\d+$/;
Msg="请输入阿拉伯数字!";
return Check(val,reg);
}
……
你可以根据你所定义的类型做不同的js判断。
现在,我们把代码编译下,加入到工具箱中。可以看我们的控件在工具箱中呈现。
图- 4
图- 5
可以看到,我们现在可以验证的数据类型有
图- 6
可以绑定的控件有:
图- 7
开发效果:
图- 8
图- 9
用户界面效果
图- 10
当然您也可以改显示效果了,如在页面某个位置中提示,但我觉得没有这个直接,例如:表单很多,一页显示不完的页面,就比较难找到提示错误数据的表单。