將驗證控制項新增至 DataList 的編輯介面 (C#)

作者 :Scott Mitchell

下載 PDF

在本教學課程中,我們將瞭解如何將驗證控件新增至 DataList 的 EditItemTemplate,以提供更易懂的編輯使用者介面。

簡介

到目前為止,在 DataList 編輯教學課程中,即使遺漏產品名稱或負價等使用者輸入無效,DataLists 編輯介面也未包含任何主動式使用者輸入驗證。 在 上述教學課程中, 我們已檢查如何將例外狀況處理程式代碼新增至 DataList 事件處理程式 UpdateCommand ,以攔截並正常顯示任何引發之例外狀況的相關信息。 不過,在理想情況下,編輯介面會包含驗證控件,以防止使用者第一次輸入這類無效的數據。

在本教學課程中,我們將瞭解如何將驗證控件新增至 DataList s EditItemTemplate ,以提供更易懂的編輯使用者介面。 具體而言,本教學課程會採用在上一個教學課程中建立的範例,並增強編輯介面以包含適當的驗證。

步驟 1:復寫處理 BLL 和 DAL-Level 例外狀況的範例

處理 BLL 和 DAL-Level 例外 狀況教學課程中,我們建立了一個頁面,其中列出兩欄可編輯 DataList 中產品的名稱和價格。 本教學課程的目標是要增強 DataList 的編輯介面,以包含驗證控件。 特別是,我們的驗證邏輯會:

  • 要求提供產品名稱
  • 確定為價格輸入的值是有效的貨幣格式
  • 確定針對價格輸入的值大於或等於零,因為負 UnitPrice 值不合法

我們必須先將範例從 ErrorHandling.aspx 資料夾中的頁面EditDeleteDataList複寫至本教學課程的頁面,才能增強先前的範例以包含驗證。 UIValidation.aspx 若要達成此目的,我們必須複製 ErrorHandling.aspx 頁面的宣告式標記及其原始程式碼。 執行下列步驟,先複製宣告式標記:

  1. ErrorHandling.aspx在 Visual Studio 中開啟頁面
  2. 移至頁面宣告式標記 (按下頁面底部的 [來源] 按鈕)
  3. 複製 和 </asp:Content> 標籤內的<asp:Content>文字, (行 3 到 32) ,如圖 1 所示。

複製 asp:Content> 控件內的<文字

圖 1:複製控件內的 <asp:Content> 文字 (按兩下即可檢視完整大小的影像)

  1. UIValidation.aspx開啟頁面
  2. 移至頁面宣告式標記
  3. 貼上 控件內的 <asp:Content> 文字。

若要複製原始程式碼,請開啟ErrorHandling.aspx.vb頁面,並只複製 類別內的EditDeleteDataList_ErrorHandling文字。 複製三個事件處理程式 (Products_EditCommandProducts_CancelCommandProducts_UpdateCommand) 與 DisplayExceptionDetails 方法,但 請勿 複製類別宣告或 using 語句。 在類別貼上複製的EditDeleteDataList_UIValidationUIValidation.aspx.vb文字。

將內容和程式代碼從 ErrorHandling.aspxUIValidation.aspx移至 之後,請花一點時間在瀏覽器中測試頁面。 您應該會在這兩個頁面中看到相同的輸出並體驗相同的功能, (請參閱圖 2) 。

UIValidation.aspx頁面會模擬 ErrorHandling.aspx 中的功能

圖 2:頁面 UIValidation.aspx 模擬 (中的 ErrorHandling.aspx 功能 按下即可檢視完整大小的影像)

步驟 2:將驗證控件新增至 DataList s EditItemTemplate

建構數據輸入表單時,請務必讓使用者輸入任何必要欄位,而且其所有提供的輸入都是合法、格式正確的值。 為了協助確保使用者的輸入有效,ASP.NET 提供五個內建驗證控件,其設計目的是要驗證單一輸入Web控件的值:

如需這五個控件的詳細資訊,請參閱將驗證控件新增至編輯和插入介面教學課程,或參閱 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 智慧標記中的 [編輯範本] 連結,或透過宣告式語法,透過 Designer 執行這項工作。 讓我們從 [設計] 檢視使用 [編輯範本] 選項逐步執行程式。 選擇編輯 DataList s EditItemTemplate之後,將 RequiredFieldValidator 從 [工具箱] 拖曳至範本編輯介面,然後將它放在 TextBox 之後 ProductName

將 RequiredFieldValidator 新增至 ProductName TextBox 之後的 EditItemTemplate

圖 3:將 RequiredFieldValidator 新增至 EditItemTemplate AfterProductName TextBox (按兩下即可檢視完整大小的影像)

所有驗證控件的運作方式是驗證單一 ASP.NET Web 控件的輸入。 因此,我們需要指出我們剛才新增的 RequiredFieldValidator 應該根據 ProductName TextBox 進行驗證;這可藉由將驗證控件的 ControlToValidate 屬性 設定為 ID 適當 Web 控件的 ProductName (,在此實例中) 。 接下來,將 ErrorMessage 屬性 設定為 [您必須提供產品名稱],並將 Text 屬性 設定為 *。 Text如果提供屬性值,則為驗證控件在驗證失敗時所顯示的文字。 ErrorMessage ValidationSummary 控件會使用必要屬性值;如果Text省略屬性值,ErrorMessage則屬性值會顯示在無效輸入上的驗證控件。

設定 RequiredFieldValidator 的這三個屬性之後,您的畫面看起來應該類似圖 4。

設定 RequiredFieldValidator s ControlToValidate、ErrorMessage 和 Text 屬性

圖 4:設定 RequiredFieldValidator s ControlToValidateErrorMessageText Properties (按兩下即可檢視完整大小的影像)

將 RequiredFieldValidator 新增至 EditItemTemplate時,所有剩餘專案都是新增產品價格 TextBox 的必要驗證。 由於 在 UnitPrice 編輯記錄時是選擇性的,因此我們不需要新增 RequiredFieldValidator。 不過,我們需要新增 CompareValidator,以確保 UnitPrice提供時,格式正確為貨幣且大於或等於 0。

將 CompareValidator 新增至 EditItemTemplate ,並將其 ControlToValidate 屬性設定為 UnitPrice,其 屬性必須大於或等於零,且不能包含貨幣符號,並將其 ErrorMessageText 屬性設定為 *。 若要指出UnitPrice值必須大於或等於 0,請將 CompareValidator s Operator 屬性設定為 GreaterThanEqual、其 屬性設定為 0,並將其 ValueToCompareType 屬性設定為 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 s CurrencyType 允許數位分隔符 (例如逗號或句號,視文化特性設定) 和前置加號或減號而定,但 不允許 貨幣符號。 此行為可能會讓使用者感到困惑,因為編輯介面目前會使用貨幣格式轉譯 UnitPrice

文字框旁出現星號,且輸入無效

圖 5:在 [輸入無效] 的文字框旁邊出現星號, (按兩下即可檢視大小完整的影像)

當驗證依原樣運作時,用戶必須在編輯記錄時手動移除貨幣符號,這無法接受。 此外,如果編輯介面中沒有無效的輸入,當按兩下時,不會有 [更新] 或 [取消] 按鈕,則會叫用回傳。 在理想情況下,不論使用者輸入是否有效,[取消] 按鈕都會將DataList傳回其預先編輯狀態。 此外,我們需要確保頁面的數據在更新 DataList UpdateCommand 事件處理程式中的產品資訊之前有效,因為驗證控件用戶端邏輯可由瀏覽器不支援 JavaScript 或已停用其支援的使用者略過。

從 EditItemTemplate s UnitPrice TextBox 移除貨幣符號

使用 CompareValidator s Currency``Type時,要驗證的輸入不得包含任何貨幣符號。 這類符號的存在會導致 CompareValidator 將輸入標示為無效。 不過,我們的編輯介面目前在 TextBox 中包含 UnitPrice 貨幣符號,這表示用戶必須先明確移除貨幣符號,才能儲存變更。 若要解決此問題,我們有三個選項:

  1. EditItemTemplate設定 ,UnitPrice讓 TextBox 值不會格式化為貨幣。
  2. 允許使用者移除 CompareValidator 並取代為正則ExpressionValidator 來輸入貨幣符號,以檢查格式正確的貨幣值。 這裡的挑戰是驗證貨幣值的正則表達式不像 CompareValidator 一樣簡單,而且如果我們想要納入文化特性設定,則需要撰寫程式代碼。
  3. 完全移除驗證控制項,並依賴 GridView RowUpdating 事件處理程式中的自訂伺服器端驗證邏輯。

讓我們前往本教學課程的選項 1。 UnitPrice目前的格式為貨幣值,因為中的 TextBox EditItemTemplate數據系結表示式: <%# Eval("UnitPrice", "{0:c}") %>。 將 Eval 語句變更為 Eval("UnitPrice", "{0:n2}"),其會將結果格式化為具有兩位數有效位數的數位。 這可以直接透過宣告式語法完成,或按兩下 DataList EditItemTemplate中 TextBox 的 [編輯 DataBindings] 連結UnitPrice

有了這項變更,編輯介面中的格式化價格會包含逗號做為群組分隔符,以及句點做為小數分隔符,但會離開貨幣符號。

注意

從可編輯介面移除貨幣格式時,我發現將貨幣符號放在 TextBox 外部的文字會很有説明。 這可作為使用者不需要提供貨幣符號的提示。

修正取消按鈕

根據預設,驗證 Web 控制件會發出 JavaScript,以在用戶端上執行驗證。 按兩下Button、LinkButton或ImageButton時,頁面上的驗證控件會在回傳發生之前檢查在用戶端上。 如果有任何無效的數據,則會取消回傳。 不過,對於某些按鈕而言,數據的有效性可能是非材料;在這種情況下,由於數據無效而取消回傳是一項細微差異。

[取消] 按鈕是這樣的範例。 假設使用者輸入無效的數據,例如省略產品名稱,然後決定她不想在全部之後儲存產品,然後按 [取消] 按鈕。 目前,[取消] 按鈕會觸發頁面上的驗證控件,該控件會報告產品名稱遺失,並防止回傳。 我們的用戶必須直接在 TextBox 中 ProductName 輸入一些文字,才能取消編輯程式。

幸運的是,Button、LinkButton 和 ImageButton 有屬性CausesValidation可以指出是否按兩下 Button 應該起始驗證邏輯, (預設為 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 (!Page.IsValid)
    return;

此外,只有在提交的數據有效時,產品才會嘗試更新。 由於驗證控制用戶端腳本,大部分的使用者將無法回傳無效的數據,但是瀏覽器不支援 JavaScript 或已停用 JavaScript 的使用者,可以略過客戶端檢查並提交無效的數據。

注意

astute 讀取器會回想一下,使用 GridView 更新數據時,我們不需要明確檢查 Page.IsValid 頁面程式代碼後置類別中的 屬性。 這是因為 GridView 會查閱 Page.IsValid 我們的 屬性,而且只有在傳回 值 True時才繼續進行更新。

步驟 3:摘要數據輸入問題

除了五個驗證控件之外,ASP.NET 還包含 ValidationSummary 控制件,其中會顯示 ErrorMessage 偵測到無效資料的驗證控件的 。 此摘要數據可以顯示為網頁上的文字,或透過強制回應的用戶端消息框顯示。 讓我們增強本教學課程,以包含摘要任何驗證問題的用戶端消息框。

若要達成此目的,請將 ValidationSummary 控件從 [工具箱] 拖曳到 Designer。 ValidationSummary 控件的位置並不重要,因為我們將它設定為只將摘要顯示為消息框。 新增控制項之後,將其 ShowSummary 屬性 設定為 False ,並將其 ShowMessageBox 屬性 設定為 True。 此外,用戶端消息框中會摘要說明任何驗證錯誤, (請參閱圖 6) 。

驗證錯誤摘要於 Client-Side 消息框中

圖 6:驗證錯誤摘要於 [Client-Side Messagebox] 中, (按兩下即可檢視完整大小的影像)

摘要

在本教學課程中,我們已瞭解如何使用驗證控件來主動確保使用者輸入有效,然後再嘗試在更新工作流程中使用它們,以減少例外狀況的可能性。 ASP.NET 提供五個驗證 Web 控制項,其設計目的是檢查特定 Web 控件的輸入,並回報輸入的有效性。 在本教學課程中,我們使用這五個控件的兩個控件 RequiredFieldValidator 和 CompareValidator,以確保提供產品名稱,且價格具有大於或等於零的貨幣格式。

將驗證控件新增至 DataList 的編輯介面就像從 [工具箱] 拖曳到 EditItemTemplate ,並設定幾個屬性一樣簡單。 根據預設,驗證控件會自動發出客戶端驗證腳本;它們也會在回傳時提供伺服器端驗證,並將累積結果儲存在屬性中 Page.IsValid 。 若要在單擊 Button、LinkButton 或 ImageButton 時略過客戶端驗證,請將按鈕的 CausesValidation 屬性設定為 False。 此外,在執行任何在回傳時提交資料的工作之前,請確定 Page.IsValid 屬性會傳 True回 。

到目前為止,我們檢查過的所有 DataList 編輯教學課程都有非常簡單的編輯介面,其中一個是 TextBox 用於產品名稱,另一個則用於價格。 不過,編輯介面可以包含不同 Web 控件的混合,例如 DropDownLists、Calendars、RadioButtons、CheckBoxes 等等。 在下一個教學課程中,我們將探討如何建置使用各種 Web 控件的介面。

快樂的程序設計!

關於作者

Scott Mitchell 是 1998 年以來,1998 年與 Microsoft Web 技術合作的 篇 ASP/ASP.NET 書籍和 4GuysFromRolla.com 作者。 Scott 是獨立的顧問、訓練者和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格連到,也可以透過其部落格來存取,網址為 http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者所檢閱。 本教學課程的首席檢閱者是 Dennis Patterson、Ken Pespisa 和 Liz Shulok。 想要檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com。