將驗證控制項新增至 DataList 的編輯介面 (VB)
在本教學課程中,我們將瞭解如何將驗證控件新增至 DataList 的 EditItemTemplate,以提供更萬無一失的編輯使用者介面。
簡介
到目前為止,在 DataList 編輯教學課程中,即使遺漏產品名稱或負價等無效的使用者輸入,DataLists 編輯介面也沒有包含任何主動式使用者輸入驗證。 在上一個教學課程中,我們已檢查如何將例外狀況處理程式代碼新增至 DataList 的UpdateCommand
事件處理程式,以便擷取和正常顯示所引發之任何例外狀況的相關信息。 不過,在理想情況下,編輯介面會包含驗證控件,以防止使用者第一次輸入這類無效的數據。
在本教學課程中,我們將瞭解如何將驗證控件新增至 DataList s EditItemTemplate
,以提供更萬無一失的編輯使用者介面。 具體而言,本教學課程會採用在上述教學課程中建立的範例,並增強編輯介面以包含適當的驗證。
步驟 1:從處理 BLL 和 DAL 層級例外狀況複寫範例
在 處理 BLL 和 DAL 層級例外狀況 教學課程中,我們建立了一個頁面,其中列出兩欄可編輯 DataList 中產品的名稱和價格。 本教學課程的目標是要增強 DataList 的編輯介面,以包含驗證控件。 特別是,我們的驗證邏輯會:
- 要求提供產品名稱
- 確定針對價格輸入的值是有效的貨幣格式
- 確定針對價格輸入的值大於或等於零,因為負
UnitPrice
值是非法的
我們必須先將範例從 ErrorHandling.aspx
EditDeleteDataList
資料夾中的頁面複寫到本教學 UIValidation.aspx
課程的頁面,才能查看增強先前的範例以包含驗證。 若要達成此目的,我們需要複製 ErrorHandling.aspx
頁面的宣告式標記和其原始程式碼。 執行下列步驟,先複製宣告式標記:
ErrorHandling.aspx
在 Visual Studio 中開啟頁面- 移至頁面的宣告式標記(按下頁面底部的[來源] 按鈕)
- 複製和
</asp:Content>
標記內的<asp:Content>
文字(第 3 到 32 行),如圖 1 所示。
圖 2:複製控制元件內的 <asp:Content>
文字(按兩下以檢視完整大小的影像)
UIValidation.aspx
開啟頁面- 移至頁面的宣告式標記
- 在控件中貼上
<asp:Content>
文字。
若要複製原始程式碼,請開啟ErrorHandling.aspx.vb
頁面,並只複製 類別內的EditDeleteDataList_ErrorHandling
文字。 複製三個事件處理程式 (、 和 ) 與 DisplayExceptionDetails
方法,但請勿複製類別宣告或using
語句。Products_UpdateCommand
Products_CancelCommand
Products_EditCommand
在類別UIValidation.aspx.vb
中貼上複製的EditDeleteDataList_UIValidation
文字。
將內容和程式代碼從 ErrorHandling.aspx
UIValidation.aspx
移至 之後,請花點時間在瀏覽器中測試頁面。 您應該會在這兩個頁面中看到相同的輸出,並體驗相同的功能(請參閱圖 2)。
圖 2:頁面 UIValidation.aspx
模擬 中的 ErrorHandling.aspx
功能(按兩下以檢視完整大小的影像)
步驟 2:將驗證控件新增至 DataList s EditItemTemplate
建構數據輸入表單時,用戶必須輸入任何必要欄位,而且其所有提供的輸入都是合法且格式正確的值。 為了協助確保使用者的輸入有效,ASP.NET 提供五個內建驗證控件,其設計目的是驗證單一輸入Web控件的值:
- RequiredFieldValidator 可確保已提供值
- CompareValidator 會針對另一個 Web 控件值或常數值驗證值,或確保指定數據類型的值格式合法
- RangeValidator 可確保值在值範圍內
- RegularExpressionValidator 會針對 正則表示式驗證值
- CustomValidator 會針對自定義的使用者定義方法驗證值
如需這五個控件的詳細資訊,請參閱將驗證控件新增至編輯和插入介面教學課程,或參閱 ASP.NET 快速入門教學課程的驗證控件一節。
在本教學課程中,我們需要使用 RequiredFieldValidator 來確保已提供產品名稱的值,以及 CompareValidator,以確保輸入的價格的值大於或等於 0,並以有效的貨幣格式呈現。
注意
雖然 ASP.NET 1.x 具有相同的五個驗證控件,ASP.NET 2.0 新增了許多改進,但除了 Internet Explorer 之外,主要兩個是瀏覽器的用戶端腳本支援,以及將頁面上的驗證控件分割成驗證群組的功能。 如需 2.0 中新驗證控件功能的詳細資訊,請參閱剖析 ASP.NET 2.0 中的驗證控件。
讓我們從將必要的驗證控件新增至 DataList s EditItemTemplate
開始。 您可以透過設計工具執行這項工作,方法是單擊 DataList 智慧標記中的 [編輯範本] 連結,或透過宣告式語法來執行。 讓我們從 [設計] 檢視使用 [編輯範本] 選項逐步執行程式。 選擇編輯 DataList s EditItemTemplate
之後,將 RequiredFieldValidator 從 [工具箱] 拖曳至範本編輯介面,將它放在 TextBox 之後 ProductName
。
圖 3:將 RequiredFieldValidator 新增至 EditItemTemplate After
ProductName
TextBox (按兩下以檢視完整大小的影像)
所有驗證控件的運作方式是驗證單一 ASP.NET Web 控件的輸入。 因此,我們需要指出我們剛才新增的 RequiredFieldValidator 應該驗證 ProductName
TextBox;這是藉由將驗證控件的 ControlToValidate
屬性 設定為 ID
適當 Web 控件的 ,來完成此動作(ProductName
在此實例中為 )。 接下來,將 ErrorMessage
屬性 設定為 [您必須提供產品名稱],並將 Text
屬性 設定為 *。 如果提供,屬性值 Text
就是驗證控件在驗證失敗時所顯示的文字。 ErrorMessage
ValidationSummary 控件會使用所需的屬性值;如果Text
省略屬性值,ErrorMessage
則無效輸入上的驗證控件會顯示屬性值。
設定 RequiredFieldValidator 的這三個屬性之後,您的畫面看起來應該類似圖 4。
圖 4:設定 RequiredFieldValidator s ControlToValidate
、 ErrorMessage
和 Text
屬性 (按兩下以檢視完整大小的影像)
在 RequiredFieldValidator 新增至 EditItemTemplate
之後,剩下的一切都是新增產品價格 TextBox 的必要驗證。 UnitPrice
由於 在編輯記錄時是選擇性的,因此我們不需要新增 RequiredFieldValidator。 不過,我們確實需要新增 CompareValidator,以確保 UnitPrice
所提供的 格式正確設定為貨幣,且大於或等於 0。
將 CompareValidator 新增至 , EditItemTemplate
並將其 屬性設定 ControlToValidate
為 UnitPrice
,其 ErrorMessage
屬性必須大於或等於零,且不能包含貨幣符號,且其 Text
屬性為 *。 若要指出UnitPrice
值必須大於或等於 0,請將 CompareValidator s Operator
屬性設定為 GreaterThanEqual
、將其ValueToCompare
屬性設定為 0,並將 其 Type
屬性設定為 。Currency
新增這兩個驗證控件之後,DataList 的 EditItemTemplate
宣告式語法看起來應該如下所示:
<EditItemTemplate>
Product name:
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Eval("ProductName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must provide the product's name"
runat="server">*</asp:RequiredFieldValidator>
<br />
Price:
<asp:TextBox ID="UnitPrice" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1"
ControlToValidate="UnitPrice"
ErrorMessage="The price must be greater than or equal to zero
and cannot include the currency symbol"
Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0"
runat="server">*</asp:CompareValidator><br />
<br />
<asp:Button ID="UpdateProduct" runat="server" CommandName="Update"
Text="Update" />
<asp:Button ID="CancelUpdate" runat="server" CommandName="Cancel"
Text="Cancel" />
</EditItemTemplate>
進行這些變更之後,請在瀏覽器中開啟頁面。 如果您在編輯產品時嘗試省略名稱或輸入無效的價格值,則文本框旁邊會出現星號。 如圖 5 所示,包含貨幣符號的價格值,例如 $19.95 會被視為無效。 CompareValidator 允許Currency
Type
數位分隔符(例如逗號或句點,視文化特性設定而定),以及前置加號或減號,但不允許貨幣符號。 此行為可能會讓使用者感到困惑,因為編輯介面目前會使用貨幣格式轉譯 UnitPrice
。
圖 5:星號出現在無效輸入的文字框旁邊(按兩下以檢視完整大小的影像)
當驗證依現成運作時,使用者編輯記錄時必須手動移除貨幣符號,這是無法接受的。 此外,如果編輯介面中沒有無效的輸入,則按兩下 [更新] 或 [取消] 按鈕時,將會叫用回傳。 在理想情況下,不論使用者輸入的有效性為何,[取消] 按鈕都會將DataList傳回其預先編輯狀態。 此外,我們需要確保頁面的數據在更新 DataList UpdateCommand
事件處理程式中的產品資訊之前有效,因為驗證控件用戶端邏輯可由瀏覽器不支援 JavaScript 或停用其支援的使用者略過。
從 EditItemTemplate s UnitPrice TextBox 移除貨幣符號
使用 CompareValidator s Currency``Type
時,正在驗證的輸入不得包含任何貨幣符號。 這類符號的存在會導致 CompareValidator 將輸入標示為無效。 不過,我們的編輯介面目前在 TextBox 中包含 UnitPrice
貨幣符號,這表示用戶必須先明確移除貨幣符號,才能儲存變更。 若要解決此問題,我們有三個選項:
EditItemTemplate
設定 ,讓UnitPrice
TextBox 值不會格式化為貨幣。- 允許使用者藉由移除 CompareValidator 並取代為正則ExpressionValidator 來輸入貨幣符號,以檢查格式正確的貨幣值。 此處的挑戰是驗證貨幣值的正則表達式不像 CompareValidator 那麼簡單,而且如果我們想要納入文化特性設定,則需要撰寫程序代碼。
- 完全移除驗證控制項,並依賴 GridView
RowUpdating
事件處理程式中的自訂伺服器端驗證邏輯。
讓我們使用本教學課程的選項 1。 目前 格式 UnitPrice
為貨幣值,因為 中的 EditItemTemplate
TextBox 數據系結表示式: <%# Eval("UnitPrice", "{0:c}") %>
。 將 Eval
語句變更為 Eval("UnitPrice", "{0:n2}")
,其會將結果格式化為具有兩位數有效位數的數位。 這可以直接透過宣告式語法完成,或按兩下 DataList 中 EditItemTemplate
TextBox 的 [編輯 DataBindings] 連結UnitPrice
。
有了這項變更,編輯介面中的格式化價格會包含逗號做為群組分隔符,而句點則為小數分隔符,但會離開貨幣符號。
注意
從可編輯的介面移除貨幣格式時,我覺得將貨幣符號放在 TextBox 外部會很有説明。 這可作為使用者不需要提供貨幣符號的提示。
修正取消按鈕
根據預設,驗證 Web 控制件會發出 JavaScript,以在用戶端上執行驗證。 按兩下Button、LinkButton或ImageButton時,頁面上的驗證控件會在回傳發生之前,於客戶端檢查。 如果有任何無效的數據,則會取消回傳。 不過,對於某些按鈕而言,數據的有效性可能並不重要;在這種情況下,由於無效的數據而取消回傳是一種麻煩。
[取消] 按鈕就是這樣的範例。 假設使用者輸入無效的數據,例如省略產品名稱,然後決定她不想全部儲存產品,並點擊 [取消] 按鈕。 目前,[取消] 按鈕會觸發頁面上的驗證控件,其會報告產品名稱遺失並防止回傳。 我們的用戶必須輸入一些文字到 ProductName
TextBox 中,只是為了取消編輯程式。
幸運的是,Button、LinkButton 和 ImageButton 有一個 CausesValidation
屬性 ,可以指出是否按下按鈕應該起始驗證邏輯(預設值為 True
)。 將 [取消按鈕] 屬性 CausesValidation
設定為 False
。
確保 UpdateCommand 事件處理程式中的輸入有效
由於驗證控件發出的用戶端腳本,如果使用者輸入無效的輸入,驗證控件會取消 Button、LinkButton 或 ImageButton 控件所起始的任何回傳,其 CausesValidation
屬性為 True
(預設值)。 不過,如果使用者正在流覽已過時的瀏覽器或已停用 JavaScript 支援的瀏覽器,客戶端驗證檢查將不會執行。
所有 ASP.NET 驗證控件都會在回傳時立即重複其驗證邏輯,並透過 Page.IsValid
屬性報告頁面輸入的整體有效性。 不過,根據的值 Page.IsValid
,頁面流程不會以任何方式中斷或停止。 身為開發人員,我們有責任確保 Page.IsValid
屬性具有 值 True
,再繼續進行假設有效輸入數據的程序代碼。
如果使用者已停用 JavaScript,請瀏覽我們的頁面、編輯產品、輸入價格值太貴,然後按兩下 [更新] 按鈕,將會略過客戶端驗證,且回傳將會隨之而來。 在回傳時,ASP.NET 頁面的 UpdateCommand
事件處理程式會執行,並在嘗試剖析太昂貴至 時引發例外狀況 Decimal
。 由於我們有例外狀況處理,因此會正常處理這類例外狀況,但是我們可以避免無效的數據在第一個位置滑過,只要具有的值True
,才能繼續進行UpdateCommand
事件處理程式Page.IsValid
。
將下列程式代碼新增至事件處理程式的 UpdateCommand
開頭,緊接在 Try
區塊之前:
If Not Page.IsValid Then
Exit Sub
End If
此外,只有在送出的數據有效時,才會嘗試更新產品。 大部分的使用者都因驗證控制用戶端腳本而無法回傳無效的數據,但是瀏覽器不支援 JavaScript 或已停用 JavaScript 的使用者,可以略過客戶端檢查並提交無效的數據。
注意
精明的讀取器會記得,使用 GridView 更新數據時,我們不需要在頁面的程式代碼後置類別中明確檢查 Page.IsValid
屬性。 這是因為 GridView 會查閱 Page.IsValid
我們的 屬性,而且只有在傳回 的值 True
時,才會繼續進行更新。
步驟 3:摘要數據輸入問題
除了五個驗證控制項之外,ASP.NET 還包含 ValidationSummary 控制件,其中顯示 ErrorMessage
偵測到無效資料的驗證控制件的 。 此摘要數據可以顯示為網頁上的文字,或透過強制回應的用戶端消息框來顯示。 讓我們增強本教學課程,以包含摘要任何驗證問題的用戶端消息框。
若要達成此目的,請將 ValidationSummary 控件從工具箱拖曳至設計工具。 ValidationSummary 控件的位置並不重要,因為我們打算將它設定為只將摘要顯示為消息框。 新增 控制項之後,將其 屬性設定為 False
,並將其 ShowMessageBox
屬性設定ShowSummary
為 True
。 此外,用戶端消息框中會摘要說明任何驗證錯誤(請參閱圖 6)。
圖 6:驗證錯誤摘要於用戶端訊息框中(按兩下以檢視完整大小的影像)
摘要
在本教學課程中,我們瞭解如何使用驗證控件來主動確保使用者輸入有效,然後再嘗試在更新工作流程中使用它們,以減少例外狀況的可能性。 ASP.NET 提供五個驗證 Web 控制項,其設計目的是檢查特定 Web 控件的輸入,並回報輸入的有效性。 在本教學課程中,我們使用這五個控件的兩個控件 RequiredFieldValidator 和 CompareValidator 來確保已提供產品名稱,而且價格具有大於或等於零值的貨幣格式。
將驗證控件新增至 DataList 的編輯介面很簡單,只要從 [工具箱] 將控件拖曳到 EditItemTemplate
,並設定一些屬性即可。 根據預設,驗證控件會自動發出客戶端驗證腳本;它們也會在回傳時提供伺服器端驗證,並將累計結果儲存在屬性中 Page.IsValid
。 若要在單擊 Button、LinkButton 或 ImageButton 時略過客戶端驗證,請將 button s CausesValidation
屬性設定為 False
。 此外,在使用回傳時送出的數據執行任何工作之前,請確定 Page.IsValid
屬性會傳 True
回 。
到目前為止,我們檢查的所有 DataList 編輯教學課程都有非常簡單的編輯介面 TextBox 作為產品名稱,另一個用於價格。 不過,編輯介面可以包含不同 Web 控件的混合,例如 DropDownLists、Calendars、RadioButtons、CheckBoxes 等等。 在下一個教學課程中,我們將探討如何建置使用各種 Web 控件的介面。
祝您程式設計愉快!
關於作者
Scott Mitchell,七本 ASP/ASP.NET 書籍的作者和 4GuysFromRolla.com 創始人,自 1998 年以來便開始使用 Microsoft Web 技術。 Scott 擔任獨立顧問、講師和作家。 他的新書是 Sams Teach Yourself ASP.NET 2.0 in 24 Hours。 您可以透過 mitchell@4GuysFromRolla.com 或他的部落格 (可以在 http://ScottOnWriting.NET 找到) 與他聯繫。
特別感謝
本教學課程系列已經過許多熱心的檢閱者檢閱。 本教學課程的主要檢閱者是 Dennis Patterson、Ken Pespisa 和 Liz Shulok。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果有,請發信到 mitchell@4GuysFromRolla.com 。