第8章資料驗證控制項

Download Report

Transcript 第8章資料驗證控制項

第八章
驗證控制項
在本章中,我們將介紹工具箱/驗證頁籤的控制項,包
含RequiredFieldValidator、CompareValidator、
RangeValidator、RegularExpressionValidator、
CustomValidator、ValidationSummary等等。善用這些
控制項,可以減少或免除撰寫資料檢查的程式,進而增
進程式的穩定性。
1
第八章 驗證控制項
• 對於使用者的輸入,驗證控制項可以簡化資料檢查的程序,
使得在程式設計時,不需要進行過多非程式邏輯核心的工作。
在本章中,我們將介紹ASP.NET提供的各類驗證控制項。
2
大綱
• 8.1 驗證控制項概觀
–
–
–
–
8.1.1
8.1.2
8.1.3
8.1.4
驗證控制項的種類
驗證控制項的繼承階層
BaseValidator類別
BaseCompareValidator類別
• 8.2 RequiredFieldValidator必要輸入驗證控制項
– 8.2.1
– 8.2.2
在客戶端進行驗證
在伺服器端進行驗證
• 8.3 比較性質的驗證控制項
– 8.3.1
– 8.3.2
CompareValidator比較驗證控制項
RangeValidator範圍檢查驗證控制項
3
大綱
• 8.4 RegularExpressionValidator規則表示驗證控制項
• 8.5 CustomValidator自訂驗證控制項
– 8.5.1
– 8.5.2
•
•
•
•
自訂驗證的伺服器端驗證
自訂驗證的客戶端驗證
8.6 CausesValidation屬性
8.7 ValidationGroup屬性
8.8 ValidationSummary驗證摘要控制項
8.9 本章回顧
4
8.1 驗證控制項概觀
• 提供使用者輸入的TextBox控制項以Text屬性來代表使用者輸入的資料,
而它的型別為String字串。因此常常當需要使用者輸入數值時,我們必須
採用型別轉換函式進行轉換。而在轉換之前,則必須先確定使用者輸入的
資料是否為數值型式的字串,這些無聊的檢查工作時常造成程式撰寫的負
擔。
• 為此,ASP.NET規劃了驗證控制項,您可以預先決定使用者應該輸入哪
種資料(例如數值資料、正整數),然後直接在驗證控制項上設定,就不
必撰寫資料檢查的程式了。
– 並且只要設定EnableClientScript屬性,就會將資料驗證的工作分配到客戶端,由
JavaScript執行驗證
– 因此善用驗證控制項也可大幅降低伺服器的負擔。
• 8.1.1 驗證控制項的種類
– 驗證控制項配置於工具箱的驗證頁籤中,而我們將其功能與名稱整理於下表
中。
5
8.1.1
驗證控制項的種類
6
8.1.2
驗證控制項的繼承階層
• 驗證控制項除了DynamicValidator之外,其餘都規劃在
System.Web.UI.WebControls命名空間內
– (本章並不會介紹DynamicValidator,因為它還牽涉到例外)。
• 並且除了ValidationSummary類別之外,其餘的驗證控制項
都是繼承自BaseValidator類別,該類別繼承自Label類別,
故可呈現標籤型式。
• 而具有比較性質的驗證控制項還直接繼承於
BaseCompareValidator類別,完整的繼承圖如下:
7
8.1.2
驗證控制項的繼承階層
圖8-1驗證控制項的繼承圖
8
8.1.3
BaseValidator類別
• BaseValidator類別是大多數驗證控制項的父類別或祖父類別,
因此這些驗證控制項可以使用BaseValidator類別的成員。
– 而BaseValidator類別由於繼承自Label類別,故標籤控制項的成員
(例如屬性)都可以使用,但部份屬性在繼承後被改寫
– 例如ForeColor屬性繼承後設定其預設值為Color.Red,故驗證標籤顯
示的文字色彩為紅色。(ForeColor屬性詳見下表說明)
• BaseValidator類別重要的新增成員:
9
10
8.1.3
BaseValidator類別
• EnableClientScript 屬性
– 若設定了EnableClientScript屬性為True(此為預設值),當使用者按
下按鈕欲PostBack時,並不會馬上進行PostBack,而是執行客戶端的
JavaScript程式碼先進行檢查,只有當所有必要欄位都輸入了正確的
資料,才會出現實際的PostBack動作。
– 若設定了EnableClientScript屬性為False,並以按鈕進行PostBack,
則PostBack之後會馬上進行驗證(驗證工作由伺服器端完成),不論
驗證是否通過,都會執行其他程序,只不過,在驗證失敗時,會回傳
對應的錯誤訊息,因此,您仍必須透過IsVaild屬性的配合,決定其他
程序是否要正常執行。
11
8.1.3
BaseValidator類別
• IsValid 屬性
– IsValid屬性代表驗證控制項所設定的驗證是否通過測試
• 當我們設定了EnableClientScrip=True,則不通過驗證時並不會
進行PostBack動作,換句話說,進行PostBack動作代表客戶端
一定通過了該輸入控制項的驗證,在此狀況下,IsValid屬性就比
較不具用途
– (除非是擔心客戶端的資料因被竄改而略過客戶端的驗證程
序)。
• 而在設定EnableClientScrip=False的情況下,由於不論是否通過
驗證,其他程序仍舊會被執行,因此,可以在其他程序之首,先
利用IsValid屬性判斷是否已通過驗證,一般若未通過驗證,會立
即以Return敘述直接跳離程序,不執行其他的程式碼,以避免錯
誤的輸入資料使得程式產生意外的執行結果。
12
8.1.3
BaseValidator類別
• Page物件也有IsValid 屬性
– 當目前驗證群組的所有驗證控制項都通過驗證時,它將會回傳True。
– 而沒有設定驗證群組的驗證控制項稱之為「不含明確設定群組的驗證
控制項」,這些驗證控制項也會構成一個「預設群組」,而若觸發了
預設群組的驗證,則必須預設群組的所有驗證控制項都通過驗證(也
就是未設定驗證群組的所有驗證控制項都必須通過驗證)時,
Page.IsValid才會回傳True。
• 在範例8-1~8-7中,所有的驗證控制項都未設定群組,並且具備回
傳功能的按鈕也未設定驗證群組,故在該事件程序內使用
Page.IsValid就可以判定是否全部的驗證都已經通過。
13
8.1.4
類別
BaseCompareValidator
• BaseCompareValidator繼承自BaseValidator類別,而它是
CompareValidator與RangeValidator的父類別,它規範了關
於比較驗證的相關事項。
• BaseCompareValidator類別重要的新增成員:
14
8.2 RequiredFieldValidator必要
輸入驗證控制項
• 當網頁中出現多種輸入控制項時,有些可能是必要輸入欄位,有些則是非
必要輸入欄位,此時可以透過RequiredFieldValidator控制項指定哪一個
控制項是必要輸入欄位,並且在使用者未輸入時,提出警告訊息,以便提
醒使用者重新輸入。
– 請注意,一個RequiredFieldValidator控制項只能指定一個輸入控制項為必要欄位,但同
一個輸入控制項可以由多個RequiredFieldValidator控制項指定,詳見範例8-1。
• RequiredFieldValidator控制項的相關資訊如下:
– 類別:System.Web.UI.WebControls.RequiredFieldValidator類別
– 功能:針對某一個欄位,要求必須輸入。
– 輸出的標籤:Label對應的<span>標籤。但使用style屬性的
visibility:hidden、display:none來決定隱藏或不顯示。
– 重要的繼承類別:
• 繼承自System.Web.UI.WebControls.BaseValidator類別(故表8-2
可用)
15
8.2 RequiredFieldValidator
必要輸入驗證控制項
– 類別重要的新增成員:
16
8.2 RequiredFieldValidator
必要輸入驗證控制項
– 由於CompareValidator、RangeValidator、
RegularExpressionValidator等三種控制項都不會檢查輸入是否為空,
故RequiredFieldValidator控制項也常與別的驗證控制項搭配使用。
– 使用範例:見範例8-1、8-2。
17
8.2.1
在客戶端進行驗證
• 只要將驗證控制項的EnableClientScrip屬性設定為True(此
為預設值),驗證工作就會在客戶端進行,只有當所有驗證
都通過後,才會產生PostBack動作。
• 【範例8-1】
– 使用RequiredFieldValidator控制項驗證輸入欄位值是否改變或是否為
空字串。
• 範例8-1:
– 網站目錄 ASPNET\ch08\ch08_01\(檔案ch08_01.aspx)
– Step1:網頁介面設計如下,並設定控制項的屬性(其餘屬性參照屬
性窗格),所有控制項皆採用絕對配置。配置RequiredFieldValidator
控制項時,和配置Label控制項類似,也是使用拖曳方式即可。
18
8.2.1
在客戶端進行驗證
19
8.2.1
在客戶端進行驗證
20
8.2.1
在客戶端進行驗證
– Step2:撰寫Button1_Click事件程序碼如下:
• 程式部分內容:
7
8
9
10
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Label3.Text = TextBox1.Text & _
"您好<br />您的留言已刊登,內容如下<br />" & TextBox2.Text
End Sub
– 範例說明:
• 只有實際進行PostBack之後才可能執行Button1_Click,而由於三
個RequiredFieldValidator控制項的EnableClientScript屬性都採預
設值True,故驗證工作會在客戶端執行,只有當驗證通過後,才
會產生PostBack動作。
21
8.2.1
在客戶端進行驗證
– Step3:執行程式。
22
8.2.1
在客戶端進行驗證
23
8.2.1
在客戶端進行驗證
24
8.2.1
在客戶端進行驗證
25
8.2.1
在客戶端進行驗證
26
8.2.1
在客戶端進行驗證
27
8.2.2
在伺服器端進行驗證
• 只要將驗證控制項的EnableClientScript屬性設定為False,驗證工作就會
在伺服器端進行,但無論是否驗證成功,相關的事件程序仍會被執行。
• 【範例8-2】
– 修改範例8-1,並將驗證工作設定由伺服器端執行,並藉此觀察當驗證發生錯
誤時,伺服器端事件程序的執行狀況。
• 範例8-2:
– 網站目錄 ASPNET\ch08\ch08_02\(檔案ch08_02.aspx)
– Step0:事先建立\ch08\ch08_02\目錄。
– Step1:將範例8-1的目錄內的兩個檔案複製到\ch08\ch08_02\目錄中,
並且在VWD中開啟ch08_02網站,然後將ch08_01.aspx修改檔名為
ch08_02.aspx。
28
8.2.2
在伺服器端進行驗證
• 【註】請在VWD中更改檔名而非在檔案總管中直接更改檔名,以
免出現非預期的狀況。
– Step2:於屬性窗格中,修改RequiredFieldValidator1、
RequiredFieldValidator2、RequiredFieldValidator3控制項的
EnableClientScript屬性為False。代表驗證工作要在伺服器端完成。
29
8.2.2
在伺服器端進行驗證
– Step3:按兩下Button1按鈕,修改Button1_Click事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
14
15
16
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
Label3.Font.Bold = False
Label3.Text = TextBox1.Text & _
"您好<br />您的留言已刊登,內容如下<br />" & TextBox2.Text
Else
Label3.Font.Bold = True '粗體
Label3.Text = "您輸入了有一些錯誤的資料,請按照輔助文字說明修正"
End If
End Sub
30
8.2.2
在伺服器端進行驗證
– 範例說明:
• (1) 這次我們修改為,只有當網頁中所有的驗證群組都驗證成功,
Label3才顯示正確內容(第9~11行),否則Label3以粗體方式顯
示提示訊息(第13~14行)。由於我們並未設定
RequiredFieldValidator控制項的群組,也未設定Button1控制項的
群組,因此必須所有的驗證控制項都通過驗證,Page.IsValid才會
是True而執行第9~11行。
• (2) 由執行結果中,您會發現,將驗證工作交由伺服器端完成時,
即使未驗證成功,Button1_Click事件程序仍會被執行。因此
IsValid屬性在使用伺服器端驗證時,特別重要。
– Step4:執行程式。
31
8.2.2
在伺服器端進行驗證
32
8.2.2
在伺服器端進行驗證
33
8.3 比較性質的驗證控制項
• 比較性質的驗證控制項包含CompareValidator、
RangeValidator等兩種控制項,其父類別皆為
BaseCompareValidator類別,故表8-3的屬性皆可使用。
34
8.3.1
CompareValidator
比較驗證控制項
• 如果想要透過單一比較運算子,對於輸入的資料進行驗證,
則可以利用CompareValidator驗證控制項來完成。例如下列
狀況:
– 1:希望輸入的資料是可轉換為某種型別的值,例如Integer整數
– 2:希望輸入的值落於某個區間,例如輸入的數值大於某個數值。
– 3:希望輸入的值和另一個輸入的值相同,例如:之前範例的確認密
碼欄位與密碼欄位應該相同。
• 以上三種狀況,第一種與型別有關,而第二種與第三種情況則與
「比較」有關。而這三種需求都可以使用CompareValidator控制
項來進行驗證。
35
8.3.1
CompareValidator
比較驗證控制項
• CompareValidator控制項的相關資訊如下:
– 類別:System.Web.UI.WebControls.CompareValidator類別
– 功能:針對某一個欄位,要求與某一個目標值比較或必須能夠轉換為
某種型別。
– 輸出的標籤:Label對應的<span>標籤。但使用style屬性的
visibility:hidden、display:none來決定隱藏或不顯示。
– 重要的繼承類別:
• 繼承自System.Web.UI.WebControls.BaseCompareValidator類別
(故表8-2、8-3可用)
– 類別重要的新增成員:
36
8.3.1
CompareValidator
比較驗證控制項
37
8.3.1
CompareValidator
比較驗證控制項
• 【Operator屬性:DataTypeCheck說明】
– 當設定Operator屬性的屬性值為DataTypeCheck時,
ControlToCompare與ValueToCompare屬性就沒有作用,此時由
BaseCompareValidator類別繼承而來的Type屬性決定了該驗證是否
成功。
38
8.3.1
CompareValidator
比較驗證控制項
– 例如您對於CompareValidator控制項設定了下列屬性:
• ControlToValidate屬性:TextBox1
• Operator屬性:DataTypeCheck
• Type屬性:Integer
– 則此時,TextBox1的內容(Text屬性)必須能夠轉型為Integer,驗證
才會成功。
• 而此處的轉型是嚴格的轉型,例如TextBox1的內容若為"3.5",則仍舊不
算轉型成功。
– 不過如果TextBox1的內容為空字串,則可以通過驗證,此時可另外安
排一個RequiredFieldValidator驗證控制項來控管,使之不允許出現空
字串
• (事實上,CompareValidator、RangeValidator、
RegularExpressionValidator等三種控制項都不會檢查資料是否為空)。
39
8.3.1
CompareValidator
比較驗證控制項
• 【Operator屬性:不為DataTypeCheck說明】
– 即使我們將Operator屬性設定為非DataTypeCheck的其他屬性值(例
如GreaterThan),並不代表Type屬性就沒有作用或者不需要判斷型
別轉換是否能夠成功。事實上,當您設定Operator=GreaterThan時,
代表的是(1)進行轉型測試,(2)進行大於比較;只有兩種狀況都成功時,
才代表驗證成功。
40
8.3.1
CompareValidator
比較驗證控制項
– 例如您對於CompareValidator控制項設定了下列屬性:
• ControlToValidate屬性:TextBox1
• Operator屬性:GreaterThan
• Type屬性:Integer
• ValueToCompare 屬性:20
– 則此時,TextBox1的內容(Text屬性)必須能夠轉型為Integer且轉型
後的值必須大於20才算是驗證成功。
• 例如TextBox1的內容若為"abc","25.5","15"都算是驗證失敗。
– 不過如果TextBox1的內容為空字串,則也可以通過驗證,此時可另外
安排一個RequiredFieldValidator驗證控制項來控管,使之不允許出現
空字串。
41
8.3.1
CompareValidator
比較驗證控制項
• 【目標值為另一個輸入控制項的內容】
– 當目標值為另一個輸入控制項的內容時,Type的屬性值預設為String,
使用於內容相等比較時,實際上是兩個字串的比較,不會牽涉到轉型
錯誤的問題,因為Text屬性原本就已經是String型別。
• 不過您如果設定了Type的屬性值為非String,則即使比較時沒有錯
誤,仍可能在轉型時發生錯誤。
42
8.3.1
CompareValidator
比較驗證控制項
– 例如您對於CompareValidator控制項設定了下列屬性:
• ControlToValidate屬性:TextBox1
• ControlToCompare 屬性:TextBox2
• Operator屬性:Equal
• Type屬性:Integer
– 則此時,不但TextBox1的內容(Text屬性)必須與TextBox2的內容一
致,並且兩者都必須能夠轉型為Integer。
• 例如TextBox1與TextBox2的內容皆為"abc",仍算是驗證失敗(失
敗出現在轉型,而非不相等)。
43
8.3.1
CompareValidator
比較驗證控制項
• 使用範例:見範例8-3。
• 【範例8-3】
– 使用CompareValidator控制項於驗證時比較使用者的輸出是否合乎規
定。
• 範例8-3:
– 網站目錄 ASPNET\ch08\ch08_03\(檔案ch08_03.aspx)
– Step1:網頁介面設計如下,並設定控制項的屬性(其餘屬性參照屬
性窗格),所有控制項皆採用絕對配置。配置CompareValidator控制
項時,和配置Label控制項類似,也是使用拖曳方式即可。
44
45
46
– 【上表說明】
• (1)TextBox3內容必須與TextBox2相同,否則CompareValidator1
驗證不會通過。
• (2)TextBox4內容必須輸入≧1的正整數,否則CompareValidator2
驗證不會通過。
• (3)TextBox5內容必須輸入正確合法的日期,否則
CompareValidator3驗證不會通過。
47
8.3.1
CompareValidator
比較驗證控制項
– Step2:撰寫Button1_Click事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Label6.Text = TextBox1.Text & "您好<br />"
Label6.Text &= "恭喜您成為會員並訂購了" & TextBox4.Text & _
"年份的電子報<br />" & _
"日後登入若忘記密碼將以生日:" & _
TextBox5.Text & "進行補寄密碼"
End Sub
– 範例說明:
• 由於全部的驗證控制項都採用預設的EnableClientScript=True,故
只有驗證工作全部通過才會產生PostBack動作而執行本程序。
– Step3:執行程式。
48
49
8.3.1
CompareValidator
比較驗證控制項
50
8.3.1
CompareValidator
比較驗證控制項
51
8.3.1
CompareValidator
比較驗證控制項
52
8.3.2 RangeValidator
範圍檢查驗證控制項
•
RangeValidator控制項可以用來驗證輸入的資料是否介於指定的範圍中。
– 它同樣使用由BaseCompareValidator類別繼承而來的Type屬性決定要比較的
範圍之資料型別,並且可以設定為String、Integer、Double、Date、
Currency等型別。
• 當設定為String時,則以Unicode作為比較值的依據。
– RangeValidator控制項具有兩個重要的屬性,MaximumValue、
MinimumValue屬性,分別用來表示指定範圍的上下界(含)。
•
RangeValidator控制項的相關資訊如下:
– 類別:System.Web.UI.WebControls.RangeValidator類別
– 功能:驗證某一個欄位的內容介於MaximumValue(含)~MinimumValue
(含)。
– 輸出的標籤:Label對應的<span>標籤。
53
8.3.2 RangeValidator
範圍檢查驗證控制項
– 重要的繼承類別:
• 繼承自System.Web.UI.WebControls.BaseCompareValidator類別(故表
8-2、8-3可用)
– 類別重要的新增成員:
54
8.3.2 RangeValidator
範圍檢查驗證控制項
• 【範例8-4】
– 使用RangeValidator驗證控制項改寫範例8-3,使得訂購年份為介於
(1~5)年的整數年,生日則設定為1900/1/1~今日-18年(因為要年滿18
歲才能訂購)。
• 範例8-4:
– 網站目錄 ASPNET\ch08\ch08_04\(檔案ch08_04.aspx)
– Step0:製作與範例8-3完全相同的介面,控制項的屬性也完全相同,
但刪除其中的CompareValidator2、CompareValidator3等兩個控制項。
– Step1:配置RangeValidator1、RangeValidator2兩個控制項於原本
CompareValidator2、CompareValidator3控制項的位置,並修正Text
屬性,網頁介面設計如下:
55
8.3.2 RangeValidator
範圍檢查驗證控制項
56
8.3.2 RangeValidator
範圍檢查驗證控制項
– Step2:於屬性窗格中,修正RangeValidator1、RangeValidator2控制
項的屬性如下。
– 【上表說明】
• (1)必須滿足1≦TextBox4內容≦5且TextBox4內容為整數,否則
RangeValidator1驗證不會通過。
• (2)RangeValidator2的MaximumValue屬性未設定,我們將於程式
執行時期才設定。
57
8.3.2 RangeValidator
範圍檢查驗證控制項
– Step3:撰寫兩個事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
:
18
Protected Sub Page_Load(sender As Object, e As System.EventArgs)
RangeValidator2.MaximumValue = CStr(Today.Year - 18) & _
"/" & CStr(Today.Month) & "/" & CStr(Today.Day)
End Sub
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
'同範例8-3的Button1_Click內容
End Sub
58
8.3.2 RangeValidator
範圍檢查驗證控制項
– 範例說明:
• Page_Load會在送出HTML給瀏覽器之前執行,所以在
第8~9行設定新的RangeValidator2的MaximumValue屬
性值,該值仍舊可以被記錄在由客戶執行的JavaScript
中。設定值為執行當日的日期-18年,所以作為最大值
可以表示TextBox5輸入的生日日期至今天已經滿18歲。
59
8.3.2 RangeValidator
範圍檢查驗證控制項
– Step4:執行程式。
60
8.3.2 RangeValidator
範圍檢查驗證控制項
61
62
8.4 RegularExpressionValidator
規則表示驗證控制項
• Regular Expression在1950年代就被發明,而後被應用於電腦的設計,早
期大多使用在程式語言的文法描述中,規範一個識別字句元(Toeken),例
如變數名稱的規定通常是第一個字元不能為數字,而第二個字元以後則可
以為字母或數字等,當時Regular Expression大多被翻譯為「正規表示
式」。
• 而後,越來越多程式語言將其用於判別使用者的輸入是否合乎某種規定,
例如身分證字號欄位第一個字元應為字母,而第二個字元以後則應為數字
等。此時,為了更普及化,Regular Expression大多被翻譯為「規則表示
式」。
• RegularExpressionValidator驗證控制項,是利用規則表示式來表達該輸
入欄位應該合乎什麼樣的規則。它只新增了一個ValidationExpression 屬
性用以記錄該規則表示式。
63
8.4 RegularExpressionValidator
規則表示驗證控制項
• RegularExpressionValidator控制項的相關資訊如下:
–
–
–
–
類別:System.Web.UI.WebControls.RegularExpressionValidator類別
功能:針對某一個欄位,判別是否符合其規則表示式。
輸出的標籤:Label對應的<span>標籤。
重要的繼承類別:
• 繼承自System.Web.UI.WebControls.BaseValidator類別(故表8-2可用)
– 類別重要的新增成員:
64
8.4 RegularExpressionValidator
規則表示驗證控制項
• .NET與JavaScript/JScript的Regular Expression
– Regular Expression是利用一些簡單的字元來代表某種規則的情況,
例如a+中的「+」,代表前方字元可出現1次以上。
• 這些特別用來描述的字元(如+)稱之為描述字元
(MetaCharacters;或翻譯為中繼字元)。而最基本的學理至少規範
了「|」、「.」、「*」、「+」、「()」等五種描述字元,其中「.」
是作為連結,因此通常省略。
• Regular Expression發展至今,已經超越了以往文法句元描述使用
的五種描述字元,每一種程式語言提供Regular Expression功能時,
大多會為了本身特性的方便而提出一些新的描述字元以表示更多
種類的規則。
65
8.4 RegularExpressionValidator
規則表示驗證控制項
– 在.NET Framework中,規則表示式甚至被歸納為一個命名空間
System.Text.RegularExpressions來管理,例如其中的Match與Regex
類別就是常用的類別。
– 理論上,在ASP.NET中使用規則表示式,應該遵循Regex類別的規範。
不過,在RegularExpressionValidator驗證控制項中,我們使用
ValidationExpression屬性設定規則表示式時,不應當以
System.Text.RegularExpressions.Regex規範的語法來撰寫,因為它
可能會必須在客戶端執行,此時我們應該以符合JavaScript/JScript支
援的語法來表示規則表示式。而JavaScript/JScript支援的規則表示式
語法是System.Text.RegularExpressions.Regex規範語法的子集,因
此在伺服器端執行也不會出現問題。
66
8.4 RegularExpressionValidator
規則表示驗證控制項
– JavaScript支援的規則表示式是類似於Perl語言的規則表示式,至於
JScript 8.0則完全支援JavaScript的規則表示式,並且可於IE瀏覽器正
確執行。
• JScript 8.0的Regular Expression
– 在微軟的msdn網站中,我們可以查閱到JScript 8.0支援的規則表示式
(Regular Expression)語法,網址如下:
• http://msdn.microsoft.com/zh-tw/library/ae5bf541.aspx
– 我們將重要的符號節錄如下表格:
67
68
69
70
71
8.4 RegularExpressionValidator
規則表示驗證控制項
– 如果您觀察了表8-8的範例,您會發現規則表示式可以表示的字串格式
包羅萬象
• 例如我們想要規定字串的格式為身分證字號、Email網址、電話號
碼格式、郵遞區號,都可以透過規則表示式來完成。
– 不過對於初學者而言,有時這是一件困難的工作,因此,設定
RegularExpressionValidator控制項的ValidationExpression屬性時,
它也提供了許多的範本,不過大多為美國、日本、歐洲地區適用,您
必須加以修改。
– 我們提供上述常見的規則表示式如下表:
72
73
8.4 RegularExpressionValidator
規則表示驗證控制項
• 【範例8-5】
– 使用RegularExpressionValidator驗證控制項改寫範例8-4,以電子郵
件作為最後欄位。
• 範例8-5:
– 網站目錄 ASPNET\ch08\ch08_05\(檔案ch08_05.aspx)
– Step0:製作與範例8-4完全相同的介面,控制項的屬性也完全相同,但刪除
其中的RangeValidator2控制項。
– Step1:配置RegularExpressionValidator1於原本RangeValidator2控制項的
位置。並修改TextBox5的寬度及Label5、RequiredFieldValidator4的相關屬性,
網頁介面設計如下:
74
8.4 RegularExpressionValidator
規則表示驗證控制項
75
8.4 RegularExpressionValidator
規則表示驗證控制項
– Step2:於屬性窗格中,選取RegularExpressionValidator1,然後按
下ValidationExpression屬性,選取網際網路電子郵件地址。
76
8.4 RegularExpressionValidator
規則表示驗證控制項
– Step3:撰寫Button1_Click事件程序碼如下:
• 程式部分內容:
7
8
9
10
11
12
13
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Label6.Text = TextBox1.Text & "您好<br />"
Label6.Text &= "恭喜您成為會員並訂購了" & TextBox4.Text & _
"年份的電子報<br />" & _
"日後登入若忘記密碼,密碼會寄往下列網址<br />" & _
TextBox5.Text
End Sub
– 範例說明:
• 如果您採用複製ch08_04.aspx方式製作ch08_05.aspx,請記得刪
除Page_Load事件程序。
– Step4:執行程式。
77
78
79
8.5 CustomValidator
自訂驗證控制項
• 前面介紹的四種驗證控制項有時無法滿足程式的需求,例如大樂透開獎只
有在周二與周五開獎,因此,我們會要求使用者的輸入日期為周二或周五
的日期。此時,我們可以採用CustomValidator驗證控制項,此控制項允
許我們自行撰寫程序作為驗證是否通過的依據,在該程序中,您應該設定
CustomValidator控制項的IsValid屬性為True或False,如此才能表示驗證
是否通過。
• CustomValidator控制項的相關資訊如下:
–
–
–
–
類別:System.Web.UI.WebControls.CustomValidator類別
功能:針對某一個欄位,判別是否符合自訂的程序檢查。
輸出的標籤:Label對應的<span>標籤。
重要的繼承類別:
• 繼承自System.Web.UI.WebControls.BaseValidator類別(故表8-2可用)
80
8.5 CustomValidator
自訂驗證控制項
– 類別重要的新增成員:
81
8.5.1
自訂驗證的伺服器端驗證
• 使用CustomValidator控制項在伺服器端驗證時,應該將驗證
的程式碼寫在ServerValidate事件對應的事件程序內,該程序
必須設定IsValid屬性以便表示驗證是否通過。
• ServerValidate對應的事件程序包含一個
System.Web.UI.WebControls.ServerValidateEventArgs型別
的args參數,它提供了事件資料給處理程序,使得我們可以
取得輸入控制項(及相關的 CustomValidator控制項)的值進行
驗證的處理。它有兩個屬性,如下所述:
– Value 屬性:讀取args.Value時,可取得輸入控制項的內容,這是一
個字串型別的屬性。
– IsValid 屬性:設定args.IsValid時,可以代表該驗證是否通過,這是
一個布林型別的屬性。
82
8.5.1
自訂驗證的伺服器端驗證
• 【範例8-6】
– 使用CustomValidator自訂驗證控制項,驗證某個日期是否為大樂透開
獎日(週二或週五),若是才通過驗證,否則不通過驗證。
• 範例8-6:
– 網站目錄 ASPNET\ch08\ch08_06\(檔案ch08_06.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕對定位)並設定屬性
(其餘屬性參照屬性窗格)。
83
8.5.1
自訂驗證的伺服器端驗證
84
8.5.1
自訂驗證的伺服器端驗證
– Step2:撰寫三個程序如下:(在月曆、驗證控制項、按鈕上各按兩
下產生)
• 程式部分內容:
7
8
9
10
Protected Sub Calendar1_SelectionChanged(sender As Object,
e As System.EventArgs)
TextBox1.Text = Calendar1.SelectedDate
End Sub
85
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Protected Sub CustomValidator1_ServerValidate(source As Object,
args As System.Web.UI.WebControls.ServerValidateEventArgs)
If args.Value = "" Then '必須先設定ValidateEmptyText屬性才可能執行到此
CustomValidator1.Text = "請選擇某一日"
args.IsValid = False
Return
End If
If CDate(args.Value).DayOfWeek = 2 Or CDate(args.Value).DayOfWeek = 5 Then
args.IsValid = True
'不需更改Text,因為驗證通過時不會顯示
Else
CustomValidator1.Text = "每逢週二週五才開獎"
args.IsValid = False
End If
End Sub
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
Label3.Text = TextBox1.Text & ",開獎如下<br />"
Else
Label3.Text = ""
End If
End Sub
86
8.5.1
自訂驗證的伺服器端驗證
– 範例說明:
• (1)第7~9行:選取月曆的某一日時執行,將日期複製到TextBox1
中,雖然TextBox1.ReadOnly設定為True,但只代表使用者不可
修改TextBox1的內容,而程式中仍可修改。
• (2)第11~23行:當資料PostBack回伺服器時,會先執行
CustomValidator1_ServerValidate事件程序,然後才會執行
Button1_Click事件程序。
– 第12~16行是判斷要驗證的文字方塊是否為空,這必須搭配
設定ValidateEmptyText屬性為True才有作用。否則,驗證的
文字方塊若為空,則資料PostBack回伺服器時根本不會執行
CustomValidator1_ServerValidate事件程序。
– 第17~22行則是資料非空時,進行是否為週二與週五的檢查。
87
8.5.1
自訂驗證的伺服器端驗證
• (3)在CustomValidator1_ServerValidate程序中,有兩種驗證錯誤
的狀況,我們可以分別設定不同的Text屬性值,用以顯示不同的驗
證錯誤原因(第13、20行)。而在此程序中,一定要設定
args.IsValid屬性,否則驗證程序毫無意義。
• (4)第25~31行:利用Page.IsValid檢查所有驗證是否通過,決定是
否繼續取出開獎球號(第27行)。
88
8.5.1
自訂驗證的伺服器端驗證
– Step3:執行程式。
89
90
8.5.1
自訂驗證的伺服器端驗證
91
8.5.2
自訂驗證的客戶端驗證
• 使用CustomValidator自訂驗證控制項也可以將驗證交由客戶
端來執行
– 不過您必須提供要執行的客戶端JavaScript函式程式碼
– 以及將該函式名稱記錄於ClientValidationFunction 屬性內。
– 至於客戶端的JavaScript函式程式碼則可以放置於.aspx檔案的末端(
</html>之後)。
• 【範例8-7】
– 使用CustomValidator自訂驗證控制項,搭配JavaSctipt函式,驗證某
個數值是否為4j+3的質數。
92
8.5.2
自訂驗證的客戶端驗證
• 1.若輸入控制項為空:由JavaSctipt函式判斷後顯示錯誤訊息A,
並且驗證失敗,不進行PostBack。
• 2.若輸入控制項非7~10000的整數:由JavaSctipt函式判斷後顯示
錯誤訊息B,並且驗證失敗,不進行PostBack。
• 3.若輸入控制項非4j+3的整數:由JavaSctipt函式判斷後顯示錯誤
訊息C,並且驗證失敗,不進行PostBack。
• 4.若輸入控制項為4j+3的整數:驗證成功並進行PostBack,由伺服
器端檢查是否為質數,若不為質數,產生錯誤訊息。
• 範例8-7:
– 網站目錄 ASPNET\ch08\ch08_07\(檔案ch08_07.aspx)
– Step1:網頁介面設計如下(所有控制項皆採絕對定位)並設定屬性
(其餘屬性參照屬性窗格)。
93
8.5.2
自訂驗證的客戶端驗證
94
95
8.5.2
自訂驗證的客戶端驗證
–7 Step2:撰寫兩個事件程序、一個isPrime函式程序如下:
Protected Function isPrime(ByVal i As Integer) As Boolean '判斷質數
8 • 程式部分內容:
Dim i_sqrt = CInt(Math.Sqrt(i))
9
10
11
12
13
14
15
16
For factor As Integer = 2 To i_sqrt
If i Mod factor = 0 Then
Return False
End If
Next
Return True
End Function
96
8.5.2
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
自訂驗證的客戶端驗證
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
If isPrime(CInt(TextBox1.Text)) = False Then
Label4.Text = "很抱歉,這個數不是質數,請重新輸入"
Else
Dim HashTableArr(CInt(TextBox1.Text), 2) As String
Label4.Text = "雜湊表陣列已產生"
End If
Else
Label4.Text = ""
End If
End Sub
Protected Sub Page_Load(sender As Object, e As System.EventArgs)
Label1.Text = "雜湊表是一種快速查閱資料的資料結構<br />"
Label1.Text &= "非完美雜湊會發生溢位,平方探測法是解決溢位的簡單策略<br />"
Label1.Text &= "通常它採用4j+3的質數做為桶數(bucket)<br />"
End Sub
97
8.5.2
自訂驗證的客戶端驗證
– 範例說明:
• (1)第7~15行:判斷傳入之參數是否為質數。檢查因數時,只需要
檢查到根號i即可,如此可以節省一些計算時間。
• (2)第17~28行:通過客戶端的驗證後,才會執行Button1_Click。
判斷是否為質數後,決定輸出錯誤訊息或產生代表雜湊表的陣列。
• (3)第30~34行:網頁初始時,設定Label1的內容。
– Step3:由於我們設定了ClientValidationFunction屬性為
ClientValidateFormula4j3,故應該提供一個JavaScript函式,名稱為
ClientValidateFormula4j3,就和ServerValidate的事件程序一樣,它
應該有兩個參數,不過JavaScript語法較為寬鬆,不必設定其型別。
我們將JavaScript的ClientValidateFormula4j3函式,撰寫於網頁末端
即可,如下:
• 程式部分內容:
67
68
</body>
</html>
98
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<script language="JavaScript" type="text/javascript">
<!-function ClientValidateFormula4j3(source, arguments)
{
if (arguments.Value == "") {
CustomValidator1.innerHTML = "桶數不可為空"
arguments.IsValid = false
return
}
if((arguments.Value < 7) || (arguments.Value >10000))
{
CustomValidator1.innerHTML = "桶數請介於7~10000"
arguments.IsValid = false
return
}
if (arguments.Value % 4 == 3) {
arguments.IsValid = true
}
else {
CustomValidator1.innerHTML = "桶數必須是(4j+3)的整數"
arguments.IsValid = false
}
}
-->
99
</script>
8.5.2
自訂驗證的客戶端驗證
– 範例說明:
• (1)第69~93行:這是我們在檔案末端加入的JavaScript程式碼,使
用的是JavaScript語法。
• (2)第71~91行:ClientValidateFormula4j3函式,arguments參數相
當於ServerValidate事件程序的args參數。程式共分三段,第
73~77行是檢查輸入欄位是否為空;第78~83行是檢查輸入欄位的
值是否介於7~10000,其中「||」運算子的功用等同於VB的「Or」
。第84~90行則是檢查輸入的值是否為4j+3型式的整數。其中「%」
運算子的功用等同於VB的「Mod」取餘數。
• (3)CustomValidator1.innerHTML是修改網頁中CustomValidator1
物件的內容,將之插入一段文字(文字中可包含HTML標籤),由
於CustomValidator1自訂驗證控制項會在輸出時,產生一個<span
id="CustomValidator1">的標籤,因此該<span>標籤對於客戶端的
JavaScript而言就是CustomValidator1物件。
100
8.5.2
自訂驗證的客戶端驗證
– Step4:執行程式。
101
8.5.2
自訂驗證的客戶端驗證
102
8.5.2
自訂驗證的客戶端驗證
103
8.5.2
自訂驗證的客戶端驗證
104
8.5.2
自訂驗證的客戶端驗證
105
8.6 CausesValidation屬性
• 到目前為止,我們已經學會很多簡單的驗證工作,但有一些根本的原理並
未探討,我們以過去學習過的幾個範例,提出下列幾個問題:
• 【Q】
– 當採用客戶端驗證時,焦點一離開TextBox,驗證就產生了,而按下Button後,驗證也
產生了,因此驗證是即時發生的。
– 假設我們擔心客戶端被竄改或使用者的瀏覽器不支援JavaScript,故而將所有驗證控制
項的EnableClientScript屬性皆設為False,由伺服器端進行驗證,此時會發現當焦點離
開TextBox時,驗證並不會立即發生,只有當按下Button後,驗證才會立即發生,這中
間有什麼緣故嗎?是否可以也產生立即的驗證呢?
• 【A】
– (以下討論的前提是EnableClientScript屬性皆設為False,也就是驗證絕不在
客戶端產生)
106
8.6 CausesValidation屬性
– 要使得伺服器端產生驗證,必須具備兩個條件:
• 1必須出現PostBack行為:按下Button就會立即進行PostBack。
• 2必須觸發PostBack行為的控制項指名要執行驗證:Button將
CausesValidation屬性預設為True,故代表要執行驗證。
– 基於Button滿足上述兩個條件,故一按下Button後,伺服器端就會立
即驗證。而TextBox是否也可以做到呢?答案是可以的,但還是有一
些些的出入,如下說明:
• 1必須出現PostBack行為:若設定TextBox的AutoPostBack屬性為
True,可以在TextBox內容產生變化時,自動PostBack。
• 2必須觸發PostBack行為的控制項指名要執行驗證:TextBox也有
CausesValidation屬性,但必須將之設定為True,PostBack之後
才會立即執行驗證。
107
8.6 CausesValidation屬性
– 總之,將TextBox的AutoPostBack與CausesValidation屬性皆設定
為True,就可以立即要求伺服器進行驗證。但何謂一些些的出入呢?
• 關鍵在於,當TextBox使用AutoPostBack回傳並因
CausesValidation為True而執行驗證時,驗證會發生在每一個控制
項。
• 而一開始輸入資料時,必定有一些TextBox控制項尚未輸入資料
(因為我們一次只能選擇一個來輸入),此時,
RequiredFieldValidator驗證必定會錯誤而顯示錯誤訊息。
• 如果您不介意發生這種狀況,只要求伺服器立即進行驗證,則輕
易就可以做到,如範例8-8。
108
8.6 CausesValidation屬性
• 【範例8-8】
– 修正8-2,將伺服器驗證改為不需要等到按下Button就立即執行驗證。
• 範例8-8:
– 網站目錄 ASPNET\ch08\ch08_08\(檔案ch08_08.aspx)
– Step0:複製範例8-2的檔案到ch08_08目錄中,在VWD中,將
ch08_02.aspx修改檔名為ch08_08.aspx。
– Step1:修改下列屬性:
– Step2:執行程式。
109
8.6 CausesValidation屬性
110
8.6 CausesValidation屬性
111
8.6 CausesValidation屬性
112
8.6 CausesValidation屬性
113
8.7 ValidationGroup屬性
• 回顧表8-2,您會發現BaseValidator類別有一個
ValidationGroup屬性,因此上述介紹的驗證控制項都有
ValidationGroup屬性
– 而我們曾在前面提及,Page.IsValid只有在「須驗證群組內的所有驗
證控制項都通過驗證」時才會被設定為True。
– 所謂群組內的所有驗證控制項,代表的是這些驗證控制項的
ValidationGroup屬性都相同,例如都是"G1"或"G2",甚至就算是空字
串也算是一個群組,只不過,這個群組是預設群組。
• 換句話說,在前面的所有範例中,所有的驗證控制項都是位於同
一群組(也就是預設群組)內。
– 除了驗證控制項之外,其餘所有具有PostBack功能的控制項(例如最
常見的按鈕)也具有ValidationGroup屬性,因此這些控制項也可以和
某些驗證控制項位於同一個群組內。
114
8.7 ValidationGroup屬性
• 亦即在前面的所有範例中,按鈕與所有的驗證控制項都是位於同
一群組(即預設群組)內,因為我們並未設定按鈕的
ValidationGroup屬性。
– 分組可讓驗證只侷限於某些驗證控制項與觸發PostBack的元件上,當
該觸發元件進行PostBack時,伺服器只會進行該群組內的驗證工作,
其餘不在群組內的驗證則不會進行。
• 即使您讀取Page.IsValid結果為True,也僅僅代表該群組內的
驗證無誤,而非網頁中所有的驗證都沒有錯誤(事實上,其
他驗證根本沒有被執行)
– 以下,我們透過一個範例來說明。
115
8.7 ValidationGroup屬性
– 【註】
– 有某些書籍說明Page.IsValid要為True,必須是Web Form中的所有驗
證控制項之IsValid皆為True(也就是所有驗證控制項皆驗證無誤),
但這樣的說明不夠清楚也不夠精確。
– 這些書籍所述的情況,僅限於所有的驗證控制項都採用預設群組時才
成立。這或許是因為某些書籍在改版時未加以注意的緣故,因為
BaseValidator.ValidationGroup屬性是.NET Framework 2.0才出現的
功能。
116
8.7 ValidationGroup屬性
• 【範例8-9】
– 使用ValidationGroup屬性進行驗證分組,共有三個按鈕
• 其中兩個分別觸發兩個有明確組名的不同組別驗證
• 而另外一個則觸發無明確組名(即預設組名)的組別驗證。
• 並且在伺服器端以Page.IsValid檢查該組別內的所有驗證是否都已
通過
• (以及證明其他組別若驗證不會通過時,並不影響Page.IsValid的
結果)。
• 範例8-9:
– 網站目錄 ASPNET\ch08\ch08_09\(檔案ch08_09.aspx)
– Step1:網頁介面設計如下,使用一個Label控制項與三個Panel面板
(Panel面板採絕對定位),但面板內的控制項則採相對定位。屬性
如下表(其餘屬性參照屬性窗格)。
117
8.7 ValidationGroup屬性
118
8.7 ValidationGroup屬性
119
8.7 ValidationGroup屬性
– Step2:驗證控制項分組與對象設定。
120
8.7 ValidationGroup屬性
– Step3:驗證控制項的其他設定。
– Step4:撰寫三個事件程序(此外檔案中還提供了一個Page_Load程
序,請自行見檔案內容) :
• 程式部分內容:
121
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
Label2.Text = "G1群組的所有驗證全部通過"
Label4.Text = "" : Label6.Text = ""
Else
Label2.Text = "G1群組的所有驗證並未全部通過"
Label4.Text = "" : Label6.Text = ""
End If
End Sub
Protected Sub Button2_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
Label4.Text = "G2群組的所有驗證全部通過"
Label2.Text = "" : Label6.Text = ""
Else
Label4.Text = "G2群組的所有驗證並未全部通過"
Label2.Text = "" : Label6.Text = ""
End If
End Sub
122
8.7 ValidationGroup屬性
27
28
29
30
31
32
33
34
35
Protected Sub Button3_Click(sender As Object, e As System.EventArgs)
If Page.IsValid = True Then
Label6.Text = "預設群組的所有驗證全部通過" '[無名群組]
Label2.Text = "" : Label4.Text = ""
Else
Label6.Text = "預設群組的所有驗證並未全部通過" '[無名群組]
Label2.Text = "" : Label4.Text = ""
End If
End Sub
– 範例說明:
• (1)由於所有驗證控制項的EnableClientScript屬性都設定為False,
因此驗證只會在伺服器端發生。
• (2)三個程序的邏輯都相同,我們以Button2_Click來做說明。
123
8.7 ValidationGroup屬性
• (3)第17~25行:當按下Button2時,會產生PostBack,然後先執行
驗證,再執行Button2_Click事件程序。當執行驗證時,由於
Button2的ValidationGroup屬性設定為"G2",故只有G2組別的驗
證會被執行,也就是RequiredFieldValidator2與
CompareValidator2兩個驗證會被檢驗。而若我們在TextBox2輸入
的是-5,則兩個驗證都會通過,此時執行Button2_Click的第18行
時,Page.IsVaild將會是True而執行19~20行。它並不會管其他非
G2群組的驗證是否通過。
• (4)在ch08_09.aspx檔案中,我們另外提供了一個Page_Load事件
程序,它的輸出將會呈現在介面的Label7處,其功能是用來讀出
網頁中所有的驗證控制項以及它所屬的群組。當您執行後可以發
現,在這個範例中,網頁的驗證控制項共有7項。所以「只有當網
頁所有的驗證控制項都通過驗證,Page.IsVaild才會是True」是不
夠正確的說法,它只適用於驗證控制項未分組的狀況。
124
8.7 ValidationGroup屬性
• (5)Page_Load事件程序中的程式碼節取自msdn的範例,當中牽涉到使用
IEnumerator介面指標(Current cursor)讀取集合元素,由於超出本書範圍,
故不多加說明。(筆者對此的相關著作,見於Java初學指引的14.5節,但
它比較類似C#的語法)
– Step5:執行程式。
125
8.7 ValidationGroup屬性
126
128
8.8 ValidationSummary
驗證摘要控制項
• 在表8-2中,我們可以發現驗證控制項有一個ErrorMessage屬
性,它的用途有兩項:
– 功能1:當Text屬性未設定(即空字串)時,若驗證失敗,則以
ErrorMessage屬性作為驗證失敗時顯示的文字。
– 功能2:當驗證失敗時,提供給ValidationSummary摘要控制項擷取的
錯誤訊息。
• 【註】如果您不想顯示Text屬性,則應該將驗證控制項的Display屬性設
定為None,而非將Text屬性設定為空白。
• 在圖8-1的類別繼承圖中可以發現,ValidationSummary驗證摘要控制項並
非繼承自BaseValidator類別,因此它雖然被分配在工具箱驗證頁籤中,
但實際上並沒有驗證效果。它只有蒐集驗證失敗資訊(ErrorMessage)
與顯示失敗資訊的功能。
129
8.8 ValidationSummary
驗證摘要控制項
• ValidationSummary控制項的相關資訊如下:
– 類別:System.Web.UI.WebControls.ValidationSummary類別
– 功能:蒐集驗證失敗資訊(ErrorMessage)與顯示失敗資訊。
– 輸出的標籤:依照選取的顯示種類(DisplayMode屬性決定)而出現
不同的對應標籤如下:
• 當設定為BulletList:輸出
<div><ul><li>…</li><li>…</li></ul></div>
• 當設定為List:輸出<div>…<br />…<br /></div>
• 當設定為 SingleParagraph:輸出<div>… … …<br /></div>
– 繼承類別:
• 直接繼承自System.Web.UI.WebControls.WebControl類別
– 類別重要的新增成員:
130
8.8 ValidationSummary
驗證摘要控制項
131
8.8 ValidationSummary
驗證摘要控制項
• 【ShowMessageBox與ShowSummary 屬性說明】
– 代表要將資訊顯示在訊息方塊(ShowMessageBox=True)或網頁
中(ShowSummary=True)。若兩個屬性都為 true,則驗證摘要會
同時顯示在訊息方塊和網頁。
• 【範例8-10】
– 修正8-3,使用ValidationSummary控制項蒐集各驗證控制項的
ErrorMessage。
• 範例8-10:
– 網站目錄 ASPNET\ch08\ch08_10\(檔案ch08_10.aspx)
– Step0:複製範例8-3的檔案到ch08_10目錄中,在VWD中,將
ch08_03.aspx修改檔名為ch08_10.aspx。
132
8.8 ValidationSummary
驗證摘要控制項
– Step1:修改下列屬性:
– Step2:加入ValidationSummary1控制項(設定為絕對位置),並設
定控制項的屬性(其餘屬性參照屬性窗格),介面如下:
133
8.8 ValidationSummary
驗證摘要控制項
134
8.8 ValidationSummary
驗證摘要控制項
– Step3:將Button1_Click簡化如下。
7
8
9
Protected Sub Button1_Click(sender As Object, e As System.EventArgs)
Label6.Text = TextBox1.Text & "並訂購了" & TextBox4.Text & "年份的電子報"
End Sub
– Step4:執行程式。
135
8.8 ValidationSummary
驗證摘要控制項
136
137
138
139
8.8 ValidationSummary
驗證摘要控制項
• 【Display:None】
– 若想要不顯示驗證控制項的Text屬性值,只顯示ValidationSummary
控制項蒐集的ErrorMessage。則應該將驗證控制項的Display屬性全
部設定為None。
– 例如我們複製ch08_10.aspx為ch08_10_1.aspx,並在Page_Load做
如此的修改後(您也可以於屬性窗格中自行設定為None
Protected Sub Page_Load(sender As Object, e As System.EventArgs)
RequiredFieldValidator1.Display = ValidatorDisplay.None
RequiredFieldValidator2.Display = ValidatorDisplay.None
RequiredFieldValidator2N.Display = ValidatorDisplay.None
RequiredFieldValidator3.Display = ValidatorDisplay.None
RequiredFieldValidator4.Display = ValidatorDisplay.None
CompareValidator1.Display = ValidatorDisplay.None
CompareValidator2.Display = ValidatorDisplay.None
CompareValidator3.Display = ValidatorDisplay.None
End Sub
140
8.8 ValidationSummary
驗證摘要控制項
– 執行結果如下圖:
141
8.8 ValidationSummary
驗證摘要控制項
• 【ShowMessageBox:True】
– 如果設定ValidationSummary控制項的ShowMessageBox 屬性為True,
則會將蒐集來的ErrorMessage以訊息方塊顯示。
142
8.8 ValidationSummary
驗證摘要控制項
– 下圖是將ch08_10_1.aspx複製為ch08_10_2.aspx,並修改
ValidationSummary1控制項的ShowMessageBox屬性為True,並將
ShowSummary屬性設定為False的執行結果:
143
8.8 ValidationSummary
驗證摘要控制項
• 【ValidationGroup屬性】
– ValidationSummary控制項也有ValidationGroup屬性,因此可以將之
加入某一個驗證群組中
• 當加入某一個驗證群組後,它就只會蒐集該組驗證控制項的ErrorMessage,
並且只有在該組觸發元件觸發了驗證之後,才會進行蒐集的動作。
• 如果沒有設定ValidationGroup屬性,則視同該ValidationSummary控制項
加入了預設群組。當加入某一個驗證群組後,它就只會蒐集該組驗證控制
項的ErrorMessage,並且只有在該組觸發元件觸發了驗證之後,才會進行
蒐集的動作。
• 【範例8-11】
– 改寫範例8-9,使用三個ValidationSummary控制項蒐集G1、G2、預
設群組等三個驗證群組的ErrorMessage,並以三種方式顯示。而所有
的驗證控制項皆設定Display屬性為None。
144
8.8 ValidationSummary
驗證摘要控制項
• 範例8-11:
– 網站目錄 ASPNET\ch08\ch08_11\(檔案ch08_11.aspx)
– Step0:複製ch08_09.aspx為ch08_11.aspx,刪除Label7,並將所有
驗證控制項的Display屬性設定為None。
– Step1:加入三個ValidationSummary控制項於三個Panel面板中,並
設定其屬性如下表(其餘屬性參照屬性窗格)。
145
8.8 ValidationSummary
驗證摘要控制項
146
8.8 ValidationSummary
驗證摘要控制項
– Step2:修改Page_Load事件程序如下:
• 程式部分內容:
37
38
39
40
41
42
43
44
45
46
Protected Sub Page_Load(sender As Object, e As System.EventArgs)
Dim myCollection As ValidatorCollection = Page.Validators
' Get the Enumerator.
Dim myEnumerator As IEnumerator = myCollection.GetEnumerator()
' Print the values in the ValidatorCollection.
Dim myStr As String = " "
While myEnumerator.MoveNext()
myEnumerator.Current.ErrorMessage = myEnumerator.Current.Text
End While
End Sub
147
8.8 ValidationSummary
驗證摘要控制項
– 範例說明:
• 因為原本只設定了驗證控制項的Text屬性而未設定ErrorMessage
屬性,故在此將Text屬性複製給ErrorMessage屬性(第44行),
以便讓ValidationSummary控制項蒐集。由於上述語法較為複雜
(同範例8-9的原因),故您也可以刪除整個Page_Load事件程序,
然後手動在屬性窗格中,一一設定驗證控制項的ErrorMessage屬
性。
– Step3:執行程式。
• 【程式執行結果】:
148
8.8 ValidationSummary
驗證摘要控制項
149
150
8.9 本章回顧
• 在本章中,我們介紹了工具箱驗證頁籤中大多數的控制項,包含
RequiredFieldValidator、CompareValidator、RangeValidator、
RegularExpressionValidator、CustomValidator等五種驗證控制項,它們
全都直接或間接繼承自BaseValidator類別。
–
–
–
–
RequiredFieldValidator可以用於檢查欄位是否為空。
CompareValidator與RangeValidator則可以透過簡單的設定限制欄位值
而RegularExpressionValidator則是以規則表示式來規定欄位值。
至於CustomValidator則允許我們自行製作驗證程序。
• 當驗證錯誤時,可以顯示各驗證控制項的Text屬性值,若未設定則會顯示
ErrorMessage屬性值。
– 除此之外,我們也可以利用ValidationSummary搜尋各控制項的ErrorMessage屬性值來
顯示驗證錯誤的訊息。
151
8.9 本章回顧
• EnableClientScript屬性使得驗證可以客戶端執行,也可以在
伺服器端執行
– 當欲在伺服器端執行時,觸發的元件必須能夠產生PostBack(例如按
鈕)或設定為AutoPostBack(例如TextBox),同時它還必須擁有
CausesValidation屬性,並將之設定為True,伺服器端才會進行驗證。
– 當您採用了伺服器端驗證時,必須注意,即使驗證失敗,原本應該執
行的事件程序(例如Button_Click)仍會被執行,因此應該在程序中,
透過IsValid屬性判斷驗證失敗或通過,而採取不同的對應策略。
152
8.9 本章回顧
• 除了基本的介紹之外,我們也說明如何透過ValidationGroup屬性設定分
組驗證的機制,並且釐清了Page.IsValid只有在群組內的驗證都通過時,
才會被設定為True。
• 簡言之,善加利用驗證控制項有兩個好處如下:
– 若設定驗證由客戶端執行,可以減輕伺服器的負擔。
– 程式設計師在主要的事件程序中,只需要專注於程式核心邏輯的設計
,而不必過於擔心輸入的資料非預期的資料。您只要在事件程序的開
頭加上If Page.IsValid=False Then Return即可。如此可以將檢查資料
的工作分擔給驗證控制項來執行。
• 事實上,驗證控制項只能防止一些錯誤資料的輸入,而不可能完全避免,
因此在後面章節中,我們將介紹例外處理機制,兩者互相搭配後,將可以
使得我們設計的程式更穩定而不易出錯。
153
本章習題
154