為了更好的建立互動式Web應用程式,加強應用程式安全性(例如,防止腳本入侵等),開發人員應該對使用者輸入的部分提供驗證功能。過去,輸入驗證功能基本由自行編寫的用戶端腳本來完成這種實作方法既繁瑣,又容易出現錯誤。随着技術的發展,ASP.NET技術通過提供一系列驗證控件來克服這些缺點,例如,RequiredFieldValidator、CompareValidator、RangeValidator等。使用這些驗證控件,開發人員可以向Web頁面添加輸入驗證功能,例如定義驗證規則、定義向使用者顯示的錯誤資訊内容等。通常情況下,ASP.NET提供的驗證控件可以滿足大多數Web應用的需要,然而,在某些情況下,内置的驗證控件還是無法完成應用需求對資料輸入的特殊要求。為了彌補這個缺憾,ASP.NET 2.0定義了一個可以在控件開發中使用的可擴充驗證架構。開發人員可以通過使用這個驗證架構自行定義驗證控件。本文将對實作驗證控件的重要方面進行介紹,内容包括内置驗證控件概述,驗證架構等等。
1. 内置驗證控件概述
驗證控件完成對輸入資料進行驗證的功能。通過将驗證控件和輸入控件關聯,開發人員可以向Web頁面添加輸入驗證功能。另外,還提供了自定義驗證規則的方法和自定義錯誤資訊的内容和顯示方式等。本節将概括性介紹ASP.NET内置驗證控件。
ASP.NET 2.0共包含5個内置驗證控件:RequiredFieldValidator、CompareValidator、RangeValidator、RegularExpressionValidator和CustomValidator,這些控件直接或者間接派生自System.Web.UI.WebControls.BaseValidator。每個驗證控件執行特定類型的驗證,并且當驗證失敗時顯示自定義消息。下面簡要介紹了這5個驗證控件。
(1)RequiredFieldValidator控件
該控件用于確定被驗證的控件中包含一個值。
(2)CompareValidator控件
該控件使用比較運算符(小于、等于、大于等)将使用者輸入與一個常量值或另一控件的屬性值進行比較。
(3)RangeValidator控件
該控件用于檢查使用者的輸入是否在指定的上下限内。可以檢查數字對、字母字元對和日期對的範圍。
(4)RegularExpressionValidator控件
該控件用于檢查項與正規表達式定義的模式是否比對。這種驗證類型允許檢查可預知的字元序列,如×××号碼、電子郵件位址、電話号碼、郵政編碼等中的字元序列。
(5)CustomValidator控件
該控件用于使用您自己編寫的驗證邏輯檢查使用者輸入。這種驗證類型允許檢查在運作時導出的值。
除以上内置驗證控件外,ASP.NET 2.0還提供了一個用于顯示錯誤資訊概要的控件ValidationSummary。該控件的目的是将來自頁上所有驗證控件的錯誤資訊,一起顯示在一個位置,例如,一個消息框或者一個錯誤資訊清單。ValidationSummary控件不執行驗證,但是它可以和所有驗證控件一起使用,更準确的說,ValidationSummary可以和上述5個内置驗證控件以及自定義驗證控件,共同完成驗證功能。
在Web頁面中使用驗證控件,我們需要注意以下幾個關鍵的方面。
首先,将驗證控件與輸入控件關聯起來,然後,根據不同類型驗證控件的特征定義相關屬性。例如:所有驗證控件都要通過ContrlToValidate屬性進行關聯設定,都必須通過ErrorMessage屬性定義錯誤資訊内容;對于範圍檢查控件RangeValidator來講,必須定義MaximumValue和MinimumValue屬性來指定有效範圍的最小值和最大值;對于模式比對控件RegularExpressionValidator來講,必須使用ValidationExpression屬性指定用于驗證輸入控件的正規表達式。以上介紹的使用方式,很可能使得一個輸入控件關聯多個驗證控件,這在ASP.NET 2.0中是允許的。
其次,ASP.NET 2.0中為驗證控件提供了一個新屬性ValidationGroup。開發人員可使用使用該屬性将單個控件與驗證組相關聯,然後,使用多個ValidationSummary控件收集和報告這些組的錯誤。如果未指定驗證組,則驗證功能等效于ASP.NET 1.x中的驗證功能。如果在多個控件中指定了多個驗證組,則一定會顯示多個驗證摘要控件,因為一個驗證摘要隻顯示一個組的驗證錯誤。回發到伺服器且目前具有CausesValidation屬性的控件也引入了此ValidationGroup屬性,該屬性确定當控件導緻回發時應當驗證的控件組。如果未指定驗證組,則會驗證預設組,預設組由所有沒有顯式配置設定組的驗證程式組成。
最後,一旦在Web頁面中正确包含驗證控件,那麼開發人員就可以使用自己的代碼來測試頁或者單個驗證控件的狀态。例如,在使用輸入資料之前來測試驗證控件的IsValid屬性。如果為true,表示輸入資料有效;如果為false,表示輸入錯誤,并顯示錯誤資訊。對于Web頁面來講,隻有當所有驗證控件的IsValid都為true,即所有輸入資料都符合驗證條件時,Page類的IsValid屬性才設定為true,否則為false。另外,在頁面級驗證中,ASP.NET 2.0還提供了兩個新方法來支援驗證功能。一個是來自Page類的GetValidators方法,該方法将檢索屬于指定驗證組的驗證程式。還有一個也是來自Page類的Validate方法的重載,其允許采用驗證組作為參數。
2. 驗證控件實作機制
通常情況下,使用ASP.NET 2.0的5個内置驗證控件,可以滿足多數應用程式的需要。然而,為了提高開發的靈活性,滿足不同Web應用的需求,ASP.NET 2.0内置了一個可擴充的驗證架構。該架構定義了伺服器端和用戶端的基本實作規則。開發人員可以使用這個可擴充的驗證架構,根據應用需要設計自己的驗證控件來實作新的設計規則。
(1)伺服器端實作機制
并非所有的Web伺服器控件都支援驗證控件。可以使用驗證控件進行驗證的标準控件包括:TextBox、ListBox、DropDownList、RadioButtonList、HtmlInputText、HtmlInputFile、HtmlSelect和HtmlTextArea、FileUpload和HtmlInputPassword等。這些支援驗證控件的控件有一個共同特征,即中繼資料中包含System.Web.UI.ValidationPropertyAttribute。ValidationPropertyAttribute定義了控件用于辨別驗證屬性的中繼資料特性。除此之外,如果由以上控件派生的自定義控件類,需要支援驗證,那麼必須在控件類前定義ValidationPropertyAttribute,這樣該控件才能作為驗證目标控件。開發人員在實作自定義驗證控件過程中,必須首先了解以上所介紹的驗證目标控件内容,然後才能更好的開發控件。
為了實作自定義驗證控件,ASP.NET 2.0提供了3個重要對象:(1)System.Web.UI.IValidator;(2)System.Web.UI.WebControls.BaseValidator;(3)System.Web.UI.WebControls.CustomValidator。以上三者之間聯系緊密,由它們組成的驗證架構具有很強的靈活性和可擴充性。IValidator接口是驗證架構的基礎,任何實作該接口的類都可以作為驗證程式。BaseValidator是抽象基類,該類實作IValidator接口,并繼承System.Web.UI.WebControls.Label控件。通常情況下,自定義驗證控件都派生自該類。CustomValidator實際是一個驗證控件,開發人員可以用它來添加自定義的驗證邏輯。為了更好的說明驗證架構,下面将逐一介紹以上3個對象。
IValidator接口的定義如下:
public interface Ivalidator
{
string ErrorMessage {get; set;}
bool IsValid {get; set;}
void Validate();
}
IValidator接口的成員包括1個方法和2個屬性。ErrorMessage屬性用于擷取或設定條件驗證失敗時生成的錯誤資訊。IsValid屬性當由類實作時,擷取或設定一個值,通過該值訓示使用者在指定控件中輸入的内容是否通過驗證。Validate方法由類實作時,計算它檢查的條件并更新IsValid屬性。對于開發人員來講,如果實作的是一個普通驗證程式,而非驗證控件,那麼可以通過實作該接口來完成。其原因在于驗證架構的實作分布在Page類、BaseValidator類和驗證目标控件中。這些類之間的相關性不允許任意實作IValidator接口。對于實作自定義驗證控件,推薦的方法是繼承BaseValidator類。
BaseValidator是驗證架構中最為重要的部分。該類派生自Label類,并且實作IValidator接口。無論是内置驗證控件,還是自定義驗證控件,都必須派生自BaseValidator類。該類實作所有驗證控件都必須實作的通用屬性。下面介紹了一些常用驗證屬性。
· ControlToValidate屬性
該屬性值為String類型,其用于驗證控件将計算的輸入控件的程式設計ID。如果此為非法ID,則引發異常。
· Display屬性
該屬性值為ValidatorDisplay類型,其用于指定的驗證控件的顯示行為。此屬性可以為下列值之一:(1)None—驗證控件從不内聯顯示。如果希望僅在ValidationSummary控件中顯示錯誤資訊,則使用此選項。(2)Static—如果驗證失敗,驗證控件顯示錯誤資訊。即使輸入控件通過了驗證,也在Web頁中為每個錯誤資訊配置設定空間。當驗證控件顯示其錯誤資訊時,頁面布局不變。由于頁面布局是靜态的,同一輸入控件的多個驗證控件必須占據頁上的不同實體位置。(3)Dynamic—如果驗證失敗,驗證控件顯示錯誤資訊。當驗證失敗時,在頁上動态配置設定錯誤資訊的空間。這允許多個驗證控件共享頁面上的同一個實體位置。注意:由于驗證控件的空間是動态建立的,是以頁面的實體布局會發生更改。為了防止頁面布局在驗證控件變得可見時更改,必須調整包含驗證控件的HTML元素的大小,使其大得足以容納驗證控件的最大大小。
· ErrorMessage屬性
該屬性值為String類型,其用于當驗證失敗時,在ValidationSummary控件中顯示的錯誤資訊。如果未設定驗證控件的Text屬性,則驗證失敗時,驗證控件中仍顯示此文本。ErrorMessage屬性通常用于為驗證控件和ValidationSummary控件提供各種消息。注意:此屬性不會将特殊字元轉換為HTML實體。例如,小于号字元(<)不轉換為&lt;。這允許将HTML元素(如<IMG>元素)嵌入到該屬性的值中
&middot; IsValid屬性
該屬性值為bool類型,其用于訓示ControlToValidate屬性所指定的輸入控件是否被确定為有效。
由該類派生的驗證控件,可以不必再次實作以上通用屬性,而隻要根據應用需要另外定義一些屬性和驗證邏輯即可。例如,對于RangeValidator控件,除具有以上通用屬性外,還定義了用于限定取值範圍的MinimumValue和MaximumValue屬性,以及用于指定要比較的值的資料類型的Type屬性。此外,該控件的驗證邏輯是通過重寫BaseValidator.EvaluateIsValid方法實作的。由此看來,BaseValidator簡化了自定義驗證控件的實作過程,為控件開發人員提供了友善。
CustomValidator派生自BaseValidator類,它是5個内置驗證控件之一。通常情況下,頁面開發者使用CustomValidator來添加自定義的驗證邏輯,這隻要通過定義ServerValidate事件的事件處理方法以及ClientValidationFunction屬性來完成。由于CustomValidator不提供複用機制(通路屬性為public),是以自定義驗證控件不能自該類派生。
(2)用戶端實作機制
上文介紹了為實作驗證控件,開發人員必須掌握的3個核心對象。掌握這些對象的定義和使用方法對于開發驗證控件具有重要意義。通過它們,我們可以在伺服器驗證中添加驗證邏輯。當頁面回傳時,驗證目标控件的輸入資料被發往伺服器端參與驗證邏輯。如果輸入資料不能滿足驗證條件,那麼頁面将重新呈現,并且要求使用者再次進行輸入。整個驗證過程可能需要多次往返,這樣必然降低應用程式的易用性,并給伺服器增加負擔。
為了解決以上問題,開發人員必須學會為驗證控件添加用戶端驗證機制。如果使用者的浏覽器支援DHTML和JavaScript技術,并且頁面和驗證控件的EnableClientScript均設定為true,那麼就可以在用戶端執行驗證。用戶端驗證通過在向伺服器發送使用者輸入前,檢查使用者輸入、改變一些頁面效果來增強驗證過程。例如,通過在用戶端檢測輸入錯誤,進而避免伺服器端驗證所需要的資訊來回傳遞。伺服器端驗證總是要被執行的,這看起來好像是與用戶端驗證産生了重複,實際不然。出于安全考慮,如果某些使用者通過手工送出惡意資料,而繞過用戶端驗證,那麼伺服器端驗證的執行将對保護應用程式的安全性,甚至為伺服器的安全性提供有力支援。
在ASP.NET 2.0中,如果開發人員使用内置驗證控件實作驗證功能,那麼ASP.NET 2.0将自動産生相關的JavaScript代碼。如果開發人員檢視相關HTML源代碼,那麼将會發現有些來自WebResource.axd的JavaScript檔案連結。然而,我們是無法檢視相關檔案代碼的。這一點與ASP.NET 1.x不同。在ASP.NET 1.x中,預設情況下,在目錄&ldquo;C:\Inetpub\wwwroot\aspnet_client\system_web\版本号&rdquo;中包含一個WebUIValidation.js檔案。該檔案中包括了實作用戶端驗證的JavaScript代碼。開發人員可以通過閱讀這些代碼來了解驗證功能的具體實作方法。ASP.NET 2.0中沒有存在相關的源代碼檔案,而是通過WebResource.axd等機制來實作。
有關實作用戶端驗證的内容,主要涉及實作用戶端功能等知識。這些内容在前面的文章中已經詳細進行了講解。有興趣的讀者可閱讀有關文章。
3. 小結
本文主要介紹了内置驗證控件,以及自定義驗證控件實作機制。實際上,如果讀者開發自行實作驗證控件時,将會發現這個過程需要很多知識。例如,伺服器端程式設計語言、JavaScript、CSS、DHTML等等。是以,如果讀者希望建立高品質的驗證控件,那麼不僅要了解相關知識,而且必須達到精通的水準。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
由于"正規表達式"的強大功能,才使得微軟慢慢将正規表達式對象移植到了視窗系統上面。在書寫正規表達式的模式時使用了特殊的字元和序列。下表描述了可以使用的字元和序列,并給出了執行個體。
符描述: \:将下一個字元标記為特殊字元或字面值。例如"n"與字元"n"比對。"\n"與換行符比對。序列"\\"與"\"比對,"\("與"("比對。
:比對輸入的開始位置。
:比對輸入的結尾。
:比對前一個字元零次或幾次。例如,"zo*"可以比對"z"、"zoo"。
:比對前一個字元一次或多次。例如,"zo+"可以比對"zoo",但不比對"z"。
:比對前一個字元零次或一次。例如,"a?ve?"可以比對"never"中的"ve"。
:比對換行符以外的任何字元。
pattern) 與模式比對并記住比對。比對的子字元串可以從作為結果的 Matches 集合中使用 Item [0]...[n]取得。如果要比對括号字元(和 ),可使用"\(" 或 "\)"。
|y:比對 x 或 y。例如 "z|food" 可比對 "z" 或 "food"。"(z|f)ood" 比對 "zoo" 或 "food"。
n}:n 為非負的整數。比對恰好n次。例如,"o{2}" 不能與 "Bob 中的 "o" 比對,但是可以與"foooood"中的前兩個o比對。
n,} :n 為非負的整數。比對至少n次。例如,"o{2,}"不比對"Bob"中的"o",但是比對"foooood"中所有的o。"o{1,}"等價于"o+"。"o{0,}"等價于"o*"。
n,m} :m 和 n 為非負的整數。比對至少 n 次,至多 m 次。例如,"o{1,3}" 比對 "fooooood"中前三個o。"o{0,1}"等價于"o?"。
xyz] :一個字元集。與括号中字元的其中之一比對。例如,"[abc]" 比對"plain"中的"a"。
^xyz] :一個否定的字元集。比對不在此括号中的任何字元。例如,"[^abc]" 可以比對"plain"中的"p".
a-z] :表示某個範圍内的字元。與指定區間内的任何字元比對。例如,"[a-z]"比對"a"與"z"之間的任何一個小寫字母字元。
^m-z] :否定的字元區間。與不在指定區間内的字元比對。例如,"[m-z]"與不在"m"到"z"之間的任何字元比對。
b :與單詞的邊界比對,即單詞與空格之間的位置。例如,"er\b" 與"never"中的"er"比對,但是不比對"verb"中的"er"。
B :與非單詞邊界比對。"ea*r\B"與"never early"中的"ear"比對。
d :與一個數字字元比對。等價于[0-9]。
D :與非數字的字元比對。等價于[^0-9]。
f :與分頁符比對。
n :與換行符字元比對。
r :與回車字元比對。
s :與任何白字元比對,包括空格、制表符、分頁符等。等價于"[ \f\n\r\t\v]"。
S :與任何非空白的字元比對。等價于"[^ \f\n\r\t\v]"。
t :與制表符比對。
v :與垂直制表符比對。
w :與任何單詞字元比對,包括下劃線。等價于"[A-Za-z0-9_]"。
W :與任何非單詞字元比對。等價于"[^A-Za-z0-9_]"。
num :比對 num個,其中 num 為一個正整數。引用回到記住的比對。例如,"(.)\1"比對兩個連續的相同的字元。
n:比對 n,其中n 是一個八進制換碼值。八進制換碼值必須是 1, 2 或 3 個數字長。
如,"\11" 和 "\011" 都與一個制表符比對。"\0011"等價于"\001" 與 "1"。八進制換碼值不得超過 256。否則,隻有前兩個字元被視為表達式的一部分。允許在正規表達式中使用ASCII碼。
xn:比對n,其中n是一個十六進制的換碼值。十六進制換碼值必須恰好為兩個數字長。例如,"\x41"比對"A"。"\x041"等價于"\x04" 和 "1"。允許在正規表達式中使用 ASCII 碼。
egularExpressionValidator有兩種主要的屬性來進行有效性驗證。ControlToValidate 包含了一個值進行驗證。如取出文本框中的值。如ControlToValidate="TextBox1" ValidationExpression 包含了一個正規表達式進行驗證。
了,有了上面的叙述,我們就舉個例子來說明正規表達式。比如,我們想要對使用者輸入的電子郵件進行校驗,那麼,什麼樣的資料才算是一個合法的電子郵件呢?我可以這樣輸入:[email][email protected][/email],當然我也會這樣輸入:[email][email protected][/email],但是這樣的輸入就是非法的:xxx@@com.cn或者@xxx.com.cn,等等,是以我們得出一個合法的電子郵件位址至少應當滿足以下幾個條件:
. 必須包含一個并且隻有一個符号"@"
. 第一個字元不得是"@"或者"."
. 不允許出現"@."或者.@
. 結尾不得是字元"@"或者"."
是以根據以上的原則和上面表中的文法,我們很容易的就可以得到需要的模闆如下:"= "^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$"