快精灵印艺坊 您身边的文印专家
广州名片 深圳名片 会员卡 贵宾卡 印刷 设计教程
产品展示 在线订购 会员中心 产品模板 设计指南 在线编辑
 首页 名片设计   CorelDRAW   Illustrator   AuotoCAD   Painter   其他软件   Photoshop   Fireworks   Flash  

 » 彩色名片
 » PVC卡
 » 彩色磁性卡
 » 彩页/画册
 » 个性印务
 » 彩色不干胶
 » 明信片
   » 明信片
   » 彩色书签
   » 门挂
 » 其他产品与服务
   » 创业锦囊
   » 办公用品
     » 信封、信纸
     » 便签纸、斜面纸砖
     » 无碳复印纸
   » 海报
   » 大篇幅印刷
     » KT板
     » 海报
     » 横幅

深入讲解 ASP+ 验证(三)

客户端的验证

假如您的页面启用了客户端验证,则在来回过程中会发生完全不同的事件序列。客户端的验证使用客户端 JScript® 实现。实现该验证不需要任何二进制组件。

尽管 JScript 语言的标准化做得很好,但是用于与浏览器中的 HTML 文档交互的文档对象模型 (Document Object Model, DOM) 没有广泛采用的标准。因此,客户端的验证只在 Internet Explorer 4.0 和更高版本中进行,因为该验证的对象是 Internet Explorer DOM。

从服务器的角度来说,客户端的验证只意味着验证控件将不同的内容发送到 HTML 中。除此之外,其事件序列完全一样。服务器端的检查仍旧执行。尽管看起来好像多余,但是却十分重要,因为:

某些验证控件可能不支持客户端脚本。有一个很好的例子:假如要同时使用 CustomValidator 和服务器验证函数,但是没有客户机验证函数。
安全性注重事项。某些人可以很轻易得到一个包含脚本的页面,然后禁用或更改该页面。您不应利用脚本来阻止坏数据进入您的系统,而只应是为了用户得到更快的反馈。因此,假如要使用 CustomValidator,则不应提供没有相应服务器验证函数的客户机验证函数。
每个验证控件都可以确保将一个标准的客户端脚本块发送到页面中。实际上,这只是一小部分代码,其中包含对脚本库 WebUIValidation.js 中的代码的引用。这个脚本库文件包含客户端验证的所有逻辑,该文件需单独下载,并且可以存储在浏览器的缓存中。

关于脚本库

因为验证 Web 控件脚本在脚本库中,所以不必将所有客户端验证的代码直接发送到页面中,尽管表面上好像是这样做的。主要的脚本文件引用类似如下所示:

<script language=\"javascript\"
src=\"/_aspx/1.0.9999/script/WebUIValidation.js\"></script>

默认情况下,脚本文件将安装在 \"_aspx\" 目录中默认的根目录下,并使用相对于根的脚本 include 指令调用,该指令以正斜线开头。该引用表明每个单独的对象不必包含脚本库,同一台计算机上的所有页面可以引用同一个文件。您会注重到,该路径中还有一个公用的语言运行时版本号,以便不同的运行时版本可以在同一台计算机上运行。

假如查看一下您默认的虚拟根目录,您会找到该文件并查看其中的内容。这些文件的位置在 config.web 文件中指定。config.web 文件是一个用于大多数 ASP+ 设置的 XML 文件。以下是该文件中位置的定义:

<webcontrols
clientscriptslocation=\"/_aspx/{0}/script/\"
/>

鼓励您阅读该脚本,以便深入了解发生的事件。不过,建议您不要修改这些脚本,因为它们的功能与特定的运行时版本紧密相连。在运行时版本更新时,这些脚本可能也需要相应的更新,您将或者放弃更改,或者面临脚本不工作的问题。假如特定项目必须更改这些脚本,先备份这些脚本,然后将您的项目指向备份文件,方式是使用私有的 config.web 文件替代这些文件的位置。假如字符串中包含格式指令 \"{0}\",运行时版本号将替换该指令。最好将该位置更改为一个相对引用或绝对引用。

禁用客户端的验证

有时您可能不希望进行客户端验证。假如输入字段的数目很少,客户端验证可能用处不大。您究竟每次都要有一个需要来回服务器一次的逻辑。您会发现客户机上动态出现的信息对您的布局会有负面影响。

要禁用客户端验证,应使用 Page 指令 \"clienttarget=downlevel\"。该指令类似以下 ASPX 文件的开头:

<%@ Page Language=\"c#\" clienttarget=downlevel %>

该指令的默认值为 \"auto\",表示您只对 Microsoft Internet Explorer 4.0 或更高版本进行客户端验证。

注重: 不幸的是,在 Beta 1 中,该指令并非仅仅是禁用验证,同时还会使所有 Web 控件使用 HTML 3.2 标记来处理,这可能会产生意想不到的结果。最终版本提供了更好的方式来控制这个问题。

客户端事件序列

该序列是在运行包含客户端验证的页面时发生的事件序列:

在页面载入浏览器时,需要对每个验证控件进行一些初始化。这些控件作为 <span> 标记发送,其 HTML 特性与服务器上的特性最接近。最重要的是,此时会将验证器引用的所有输入元素“挂接”。被引用的输入元素将修改其客户端事件,以便在每次输入更改时调用验证例程。
脚本库中的代码将在用户使用 tab 键在各字段之间切换时执行。某个独立的字段更改时,将重新评估验证条件,根据需要使验证器可见或不可见。
当用户尝试提交表单时,将重新评估所有验证器。假如这些验证器全部有效,表单将提交给服务器。假如存在一处或多处错误,则会出现下述情况:
提交被取消。表单并不提交给服务器。
所有无效的验证器均可见。
假如某个验证摘要包含 ShowSummary=true,则将收集来自验证控件的所有错误,并使用这些错误更新其内容。
假如某个验证摘要包含 ShowMessageBox=true,则将收集错误,并在客户机的信息框中显示这些错误。
因为在每次输入更改时或提交时会执行客户端验证控件,所以在客户机上通常会评估这些验证控件两次或两次以上。请注重,提交后,仍将会在服务器上对这些验证控件进行重新评估。

客户端 API

有一个可以在客户机上使用的小型 API,以便在您自己的客户端代码中实现各种效果。因为某些例程不可能隐藏,所以理论上讲,您可以利用客户端验证脚本所定义的所有变量、特性和函数。不过,其中许多都是可以更改的实施细节。以下总结了我们鼓励您使用的客户端对象。

表 3. 客户端对象

名称 类型 说明
Page_IsValid Boolean 变量 指出页面当前是否有效。验证脚本总是保持该变量为最新。
Page_Validators 元素数组 这是包含页面上所有验证器的数组。
Page_ValidationActive Boolean 变量 指出是否应进行验证。将此变量设置为 False 可以通过编程关闭验证。
isvalid Boolean 属性 每个客户端验证器均具有该属性,指出验证器当前是否有效。请注重,在 PDC 版本中,该属性混用大小写 (\"IsValid\")。


绕过客户端验证

您常常需要执行的一项任务是在页面上添加“取消”按钮或导航按钮。在这种情况下,即使页面上有错误,您可能也希望使用该按钮提交页面。因为客户端按钮 \"onclick\" 事件在表单的 \"onsubmit\" 事件之前发生,因此可能会避免提交检查,并绕过验证。以下说明如何使用 HTML Image 控件作为“取消”按钮完成该任务:

<input type=image runat=server
value=\"取消\"
onclick=\"Page_ValidationActive=false;\"
OnServerClick=cmdCancel_Click >

使用 Button 或 ImageButton 控件执行该任务会出现一些混淆,因为 \"onclick\" 事件假定为同名的服务器端事件。您应在客户端脚本中设置该事件:

<asp:ImageButton runat=server id=cmdImgCancel
AlternateText=\"取消\"
OnClick=cmdCancel_Click/>

<script language=\"javascript\">
document.all[\"cmdImgCancel \"].onclick =
new Function(\"Page_ValidationActive=false;\");
</script>

解决该问题的另一种方式是:对“取消”按钮进行一定的设置,使其在返回时不会触发客户端脚本中的提交事件。HtmlInputButton 和 LinkButton 控件就是这样的例子。

特别效果

另一种常见的要求是:在出错时,除了由验证器自身显示的错误信息外,还需要其它一些效果。在这种情况下,您所作的任何修改均需在服务器或客户机上同时进行。假设您需要加入一个 Label,根据输入是否有效来更改颜色。以下是如何在服务器上实现该任务:

public class ChangeColorPage : Page {
public Label lblZip;
public RegularExpressionValidator valZip;

protected override void OnLoad(EventArgs e) {
lblZip.ForeColor = valZip.IsValid? Color.Black : Color.Red;
}
}

上述方式一切都很完美,但是,只要您如上所述修改验证,就会发现除非您在客户机上进行了一样的操作,否则看起来会异常不一致。验证框架会使您避免许多这种双重效果,但是无法避免您必须在客户机和服务器上同时实现的其它效果。以下是在客户机上执行同一任务的片段:

<asp:Label id=lblZip runat=server
Text=\"Zip Code:\"/>
<asp:TextBox id=txtZip runat=server
OnChange=\"txtZipOnChange();\" /></asp:TextBox><br>
<asp:RegularExpressionValidator id=valZip runat=server
ControlToValidate=txtZip
ErrorMessage=\"无效的邮政编码\"
ValidationExpression=\"[0-9]{5}\" /><br>

<script language=javascript>
function txtZipOnChange() {
//假如客户端验证未处于活动状态,则不执行任何操作
if (typeof(Page_Validators) == \"undefined\") return;
//更改标签的颜色
lblZip.style.color = valZip.isvalid ? \"Black\" : \"Red\";
}
</script>

Beta 1 客户端 API

对于 Beta 1 版,一些可以从客户端脚本调用的函数会造成其它一些情况。

表 4. 从客户端脚本调用的函数

名称 说明
ValidatorValidate(val) 将某个客户端验证器作为输入。使验证器检查其输入并更新其显示。
ValidatorEnable(val, enable) 获取一个客户端验证器和一个 Boolean 值。启用或禁用客户端验证器。假如禁用,将不会评估客户端验证器,客户端验证器将总是显示为有效。
ValidatorHookupControl(control, val) 获取一个输入 HTML 元素和一个客户端验证器。修改或创建该元素的 change 事件,以便在更改时更新验证器。该函数适合于基于多个输入值的自定义验证器。


其特别用途是启用或禁用验证器。假如您希望验证只是在特定的情况下生效,可能需要在服务器和客户机上同时更改激活状态,否则,您会发现用户无法提交该页面。

以下是上面的示例加上一个字段,该字段只在取消选中某个复选框时才会进行验证。

public class Conditional : Page {
public HtmlInputCheckBox chkSameAs;
public RequiredFieldValidator rfvalShipAddress;
protected override void Validate() {
bool enableShip = !chkSameAs.Checked;
rfvalShipAddress.Enabled = enableShip;
base.Validate();
}
}

以下是客户端等效的代码:

<input type=checkbox runat=server id=chkSameAs
onclick=\"OnChangeSameAs();\" >与付款地址一样<br>
<script language=javascript>
function OnChangeSameAs() {
var enableShip = !event.srcElement.status;
ValidatorEnable(rfvalShipAddress, enableShip);
}
</script>


返回类别: 教程
上一教程: 《C# vs.VB.NET:Choosing Your .NET Tool》观感
下一教程: 一个功能完善的专栏治理的程序->这是asp.net的第二个应用(三)

您可以阅读与"深入讲解 ASP+ 验证(三)"相关的教程:
· 深入讲解 ASP+ 验证(一)
· 深入讲解 ASP+ 验证(四)
· 深入讲解 ASP+ 验证(二)
· asp+中常用的NameSpace的讲解
· 在ASP.NET下实现数字和字符相混合的验证码
    微笑服务 优质保证 索取样品