熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

深入講解 ASP+ 驗證(三)

2013-11-13 09:41:30  來源: .NET編程 

  客戶端的驗證

  如果您的頁面啟用了客戶端驗證則在往返過程中會發生完全不同的事件序列客戶端的驗證使用客戶端 JScript® 實現實現該驗證不需要任何二進制組件

  盡管 JScript 語言的標准化做得很好但是用於與浏覽器中的 HTML 文檔交互的文檔對象模型 (Document Object Model DOM) 沒有廣泛采用的標准因此客戶端的驗證只在 Internet Explorer 和更高版本中進行因為該驗證的對象是 Internet Explorer DOM

  從服務器的角度來說客戶端的驗證只意味著驗證控件將不同的內容發送到 HTML 中除此之外其事件序列完全相同服務器端的檢查仍然執行盡管看起來似乎多余但是卻十分重要因為

  某些驗證控件可能不支持客戶端腳本有一個很好的例子如果要同時使用 CustomValidator 和服務器驗證函數但是沒有客戶機驗證函數

  安全性注意事項某些人可以很容易得到一個包含腳本的頁面然後禁用或更改該頁面您不應利用腳本來阻止壞數據進入您的系統而只應是為了用戶得到更快的反饋因此如果要使用 CustomValidator則不應提供沒有相應服務器驗證函數的客戶機驗證函數

  每個驗證控件都可以確保將一個標准的客戶端腳本塊發送到頁面中實際上這只是一小部分代碼其中包含對腳本庫 WebUIValidationjs 中的代碼的引用這個腳本庫文件包含客戶端驗證的所有邏輯該文件需單獨下載並且可以存儲在浏覽器的緩存中

關於腳本庫

  因為驗證 Web 控件腳本在腳本庫中所以不必將所有客戶端驗證的代碼直接發送到頁面中盡管表面上似乎是這樣做的主要的腳本文件引用類似如下所示

<script language=javascript      
src=/_aspx//script/WebUIValidationjs></script>

  默認情況下腳本文件將安裝在 _aspx 目錄中默認的根目錄下並使用相對於根的腳本 include 指令調用該指令以正斜線開頭該引用表明每個單獨的對象不必包含腳本庫同一台計算機上的所有頁面可以引用同一個文件您會注意到該路徑中還有一個公用的語言運行時版本號以便不同的運行時版本可以在同一台計算機上運行

  如果查看一下您默認的虛擬根目錄您會找到該文件並查看其中的內容這些文件的位置在 configweb 文件中指定configweb 文件是一個用於大多數 ASP+ 設置的 XML 文件以下是該文件中位置的定義

    <webcontrols
        clientscriptslocation=/_aspx/{}/script/
    />        

  鼓勵您閱讀該腳本以便深入了解發生的事件不過建議您不要修改這些腳本因為它們的功能與特定的運行時版本緊密相連在運行時版本更新時這些腳本可能也需要相應的更新您將或者放棄更改或者面臨腳本不工作的問題如果特定項目必須更改這些腳本先備份這些腳本然後將您的項目指向備份文件方法是使用私有的 configweb 文件替代這些文件的位置如果字符串中包含格式指令 {}運行時版本號將替換該指令最好將該位置更改為一個相對引用或絕對引用

禁用客戶端的驗證

  有時您可能不希望進行客戶端驗證如果輸入字段的數目很少客戶端驗證可能用處不大您畢竟每次都要有一個需要往返服務器一次的邏輯您會發現客戶機上動態出現的信息對您的布局會有負面影響

  要禁用客戶端驗證應使用 Page 指令 clienttarget=downlevel該指令類似以下 ASPX 文件的開頭

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

  該指令的默認值為 auto表示您只對 Microsoft Internet Explorer 或更高版本進行客戶端驗證

  注意   不幸的是在 Beta 該指令並非僅僅是禁用驗證同時還會使所有 Web 控件使用 HTML 標記來處理這可能會產生意想不到的結果最終版本提供了更好的方法來控制這個問題

客戶端事件序列

  該序列是在運行包含客戶端驗證的頁面時發生的事件序列

  在頁面載入浏覽器時需要對每個驗證控件進行一些初始化這些控件作為 <span> 標記發送其 HTML 特性與服務器上的特性最接近最重要的是此時會將驗證器引用的所有輸入元素掛接被引用的輸入元素將修改其客戶端事件以便在每次輸入更改時調用驗證例程

  腳本庫中的代碼將在用戶使用 tab 鍵在各字段之間切換時執行某個獨立的字段更改時將重新評估驗證條件根據需要使驗證器可見或不可見

  當用戶嘗試提交表單時將重新評估所有驗證器如果這些驗證器全部有效表單將提交給服務器如果存在一處或多處錯誤則會出現下述情況
  提交被取消表單並不提交給服務器
  所有無效的驗證器均可見

  如果某個驗證摘要包含 ShowSummary=true則將收集來自驗證控件的所有錯誤並使用這些錯誤更新其內容
  
  如果某個驗證摘要包含 ShowMessageBox=true則將收集錯誤並在客戶機的信息框中顯示這些錯誤
因為在每次輸入更改時或提交時會執行客戶端驗證控件所以在客戶機上通常會評估這些驗證控件兩次或兩次以上請注意提交後仍將會在服務器上對這些驗證控件進行重新評估

客戶端 API

  有一個可以在客戶機上使用的小型 API以便在您自己的客戶端代碼中實現各種效果因為某些例程不可能隱藏所以理論上講您可以利用客戶端驗證腳本所定義的所有變量特性和函數不過其中許多都是可以更改的實施細節以下總結了我們鼓勵您使用的客戶端對象

客戶端對象

  名稱 類型 說明
  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>
documentall[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) {            
        lblZipForeColor = valZipIsValid? ColorBlack : ColorRed;
    }               
}

  上述方法一切都很完美但是只要您如上所述修改驗證就會發現除非您在客戶機上進行了相同的操作否則看起來會非常不一致驗證框架會使您避免許多這種雙重效果但是無法避免您必須在客戶機和服務器上同時實現的其它效果以下是在客戶機上執行同一任務的片段

<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=[]{} /><br>

<script language=javascript>
function txtZipOnChange() {
   //如果客戶端驗證未處於活動狀態則不執行任何操作
   if (typeof(Page_Validators) == undefined)  return;
   //更改標簽的顏色
   lor = valZipisvalid ? Black : Red;
}
</script>

Beta 客戶端 API

  對於 Beta 一些可以從客戶端腳本調用的函數會造成其它一些情況

從客戶端腳本調用的函數

  名稱 說明

  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 = !chkSameAsChecked;
            rfvalShipAddressEnabled = enableShip;
            baseValidate();
        }
    }

以下是客戶端等效的代碼

<input type=checkbox runat=server id=chkSameAs
   onclick=OnChangeSameAs(); >與付款地址相同<br>
<script language=javascript>
function OnChangeSameAs() {
    var enableShip = !eventsrcElementstatus;
    ValidatorEnable(rfvalShipAddress enableShip);
}
</script>


From:http://tw.wingwit.com/Article/program/net/201311/11341.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.