在ASP.NET 2.0中操作數(shù)據(jù)之十九:給編輯和新增界面增加驗(yàn)證控件
導(dǎo)言
在前面三節(jié)的示例中,GridView和DetailsView控件使用的是綁定列和CheckBoxField(綁定GridView和DetailsView時(shí),通過智能標(biāo)記可以令VS根據(jù)數(shù)據(jù)庫自動(dòng)增加對(duì)應(yīng)的類型)。當(dāng)編輯GridView或者DetailsView中的一行時(shí),非只讀屬性的綁定列將自動(dòng)轉(zhuǎn)為textbox,以便用戶修改現(xiàn)有的數(shù)據(jù)。同樣地,當(dāng)在DetailsView控件中新增記錄時(shí),InsertVisible屬性為true(默認(rèn)值)的綁定列會(huì)呈現(xiàn)出空的textbox,以接受用戶輸入。CheckBoxField列也是如此,通常作為只讀的checkbox顯示,新增/編輯記錄時(shí)則可以接受選擇。
盡管BoundField和CheckBoxField提供的編輯和添加界面相當(dāng)有用,卻缺乏驗(yàn)證功能。當(dāng)用戶產(chǎn)生一些數(shù)據(jù)錄入錯(cuò)誤――比如遺漏了 ProductName字段或者為UnitsInStock輸入一個(gè)無效值(如-50)――那么應(yīng)用程序?qū)牡讓訏伋鲆粋€(gè)異常。盡管我們可以很好的處理這個(gè)異常像上節(jié)教程previous tutorial中討論的,但是,一個(gè)完美的‘新增/編輯'用戶界面應(yīng)該包括驗(yàn)證控件,在第一時(shí)間阻止用戶輸入這些無效數(shù)據(jù)。
為了提供一個(gè)自定義的新增/編輯界面,需要將BoundField和CheckBoxField換成模板列(ItemplateField)。關(guān)于模板列,已經(jīng)在《Using TemplateFields in the GridView Control 和 Using TemplateFields in the DetailsView Control》教程里討論過了,由幾個(gè)處理不同行狀態(tài)的模板組成。模板列的項(xiàng)模板(ItemTemplate),用來呈現(xiàn)DetailsView或GridView控件中的只讀字段或行,而EditItemplate和InsertItemTemplate則分別是編輯和新增模式的界面模板。
在本節(jié)教程中,你會(huì)發(fā)現(xiàn)為模板列的EditItemTemplate和InsertItemTemplate提供驗(yàn)證控件來提供更健壯的用戶界面是多么的簡(jiǎn)單。明確一點(diǎn),本節(jié)教程采用《Examining the Events Associated with Inserting, Updating, and Deleting 》中創(chuàng)建的示例代碼,來增加新增/編輯時(shí)的相關(guān)驗(yàn)證。
一、復(fù)制《研究插入、更新和刪除的關(guān)聯(lián)事件》的示例代碼
在《研究插入、更新和刪除的關(guān)聯(lián)事件》教程中我們創(chuàng)建了一個(gè)頁面,并在一個(gè)可編輯的GridView中列表顯示產(chǎn)品的名字和價(jià)格。頁面還有一個(gè)DetailsView,DefaultMode 屬性設(shè)置成Insert,因此始終呈現(xiàn)為新增模式。通過DetailsView,用戶可以錄入名字和價(jià)格增加新的產(chǎn)品,點(diǎn)擊Insert后,新產(chǎn)品就被增加到系統(tǒng)里(見圖1)。
圖1:以前的代碼允許用戶增加新的產(chǎn)品或修改已有的產(chǎn)品
本節(jié)教程的目標(biāo)是為DetailsView和GridView提供驗(yàn)證控件。更精確一些,此驗(yàn)證邏輯將是:
· 新增/編輯產(chǎn)品時(shí)name為必填項(xiàng)
· 新增記錄時(shí)price為必填項(xiàng);編輯時(shí)依然需要價(jià)格,并且在GridView的RowUpdating事件處理中應(yīng)用上節(jié)教程previous tutorial中的程序邏輯
· 確保輸入的price是有效的貨幣格式
在考慮為前面代碼增加驗(yàn)證之前,我們首先需要復(fù)制上節(jié)教程previous tutorial 示例DataModificationEvents.aspx中的代碼到本節(jié)教程的UIValidation.aspx頁面上。要完成此點(diǎn)需要復(fù)制DataModificationEvents.aspx頁面的元素標(biāo)記和它的后臺(tái)代碼。先按下面步驟拷貝元素標(biāo)記:
1.在Visual Studio中打開DataModificationEvents.aspx
2.轉(zhuǎn)到頁面的源視圖(單擊頁面底部的源(Source)按鈕)
3.拷貝<asp:Content> 至 </asp:Content> 標(biāo)記間的文本(3到44行),見圖2。
圖2:拷貝<asp:Content> 控件中的文本
4.打開UIValidation.aspx頁
5.轉(zhuǎn)到頁面的源視圖
6.粘貼文本到<asp:Content>控件
然后打開代碼文件DataModificationEvents.aspx.cs,拷貝EditInsertDelete_DataModificationEvents 類中的代碼,及3個(gè)事件處理(Page_Load, GridView1_RowUpdating, 和 ObjectDataSource1_Inserting),注意不要把類聲明和using語句也拷貝過來,然后將它們粘貼到UIValidation.aspx.cs中的 EditInsertDelete_UIValidation里。
上面的工作完成后,不要急著動(dòng)手,先砌杯茶在瀏覽器里查看一下是否有誤,這兩個(gè)頁面應(yīng)該具有同樣的輸出和功能。(參照?qǐng)D1 ,DataModificationEvents.aspx運(yùn)行時(shí)的抓圖)。
二、將綁定列轉(zhuǎn)換為模板列
要增加驗(yàn)證控件到新增/編輯界面,DetailsView 和 GridView必須將綁定列轉(zhuǎn)換為模板列。要實(shí)現(xiàn)此轉(zhuǎn)換,先點(diǎn)擊GridView的智能標(biāo)記(譯者:GridView右上角的箭頭),再選擇‘編輯列 …'(Edit Columns),在左邊依次選擇綁定字段并點(diǎn)擊‘將此字段轉(zhuǎn)換為TemplateField'鏈接(英文版是Convert this field into a TemplateField,下同)。
圖3:將DetailsView和GridView的綁定列轉(zhuǎn)換為模板列
通過剛才操作的字段(英文版是Fields)對(duì)話框,綁定列可以轉(zhuǎn)換為模板列,同樣擁有了只讀,編輯,新增等原有功能。下面的代碼顯示了 DetailsView中轉(zhuǎn)換為模板列后的ProductName字段的元素標(biāo)記:
<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName"> <EditItemTemplate> <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("ProductName") >'></asp:TextBox> </EditItemTemplate> <InsertItemTemplate> <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("ProductName") %>'></asp:TextBox> </InsertItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Bind("ProductName") %>'></asp:Label> </ItemTemplate> </asp:TemplateField>
注意該模板列自動(dòng)創(chuàng)建了三個(gè)模板列,ItemTemplate, EditItemTemplate以及InsertItemTemplate。項(xiàng)模板ItemTemplate使用Label Web控件簡(jiǎn)單顯示字段值(ProductName),而EditItemTemplate和InsertItemTemplate則使用TextBox控件并利用其Text屬性來處理相關(guān)的數(shù)據(jù)。由于我們?cè)陧撁嫔现皇褂肈etailsView實(shí)現(xiàn)新增,你可以刪除ItemTemplate和EditItemTemplate,當(dāng)然留著也無關(guān)緊要。
由于GridView不支持DetailsView內(nèi)建的新增功能,將GridView的ProductName字段轉(zhuǎn)換為模板列,并只保留ItemTemplate和 EditItemTemplate:
<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName"> <EditItemTemplate> <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("ProductName") %>'></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Bind("ProductName") %>'></asp:Label> </ItemTemplate> </asp:TemplateField>
通過點(diǎn)擊‘將此字段轉(zhuǎn)換為TemplateField'鏈接,Visual Studio創(chuàng)建了一個(gè)模板列模擬綁定列的界面,這一點(diǎn)可以通過在瀏覽器里查看頁面來證實(shí),替換前后外觀和行為應(yīng)該是完全一致的。
注意:可以根據(jù)需要在模板里隨意定制編輯界面。例如,也許我們對(duì)UnitPrice字段使用一個(gè)小一點(diǎn)的TextBox。要實(shí)現(xiàn)這一點(diǎn)可以通過設(shè)置 TextBox的Columns屬性或者通過Width屬性指定一個(gè)固定寬度。下節(jié)教程會(huì)討論如何用其它的數(shù)據(jù)輸入Web控件替換TextBox來定制編輯界面。
三、為GridView的項(xiàng)編輯模板(EditItemTemplate)增加驗(yàn)證控件
創(chuàng)建數(shù)據(jù)錄入表單時(shí),限制用戶錄入必填的,合法的以及格式化的數(shù)據(jù)十分重要。為確保用戶錄入數(shù)據(jù)都是有效的,ASP.NET提供了5種內(nèi)建的驗(yàn)證控件來驗(yàn)證單一控件的值:
· RequiredFieldValidator – 計(jì)算輸入控件的值以確保用戶輸入值
· CompareValidator – 將輸入控件的值同常數(shù)值或其他輸入控件的值相比較,以確定這兩個(gè)值是否與由比較運(yùn)算符(小于、等于、大于、類型等等)指定的關(guān)系相匹配
· RangeValidator – 計(jì)算輸入控件的值,以確定該值是否在指定的上限與下限之間
· RegularExpressionValidator – 計(jì)算輸入控件的值,以確定該值是否與某個(gè)正則表達(dá)式 所定義的模式相匹配
· CustomValidator – 計(jì)算輸入控件的值以確定它是否通過自定義的驗(yàn)證邏輯
關(guān)于這五種控件的更多信息,請(qǐng)參閱 《ASP.NET Quickstart Tutorials》中的Validation Controls section。
本節(jié)教程中,對(duì)于DetailsView和GridView中的ProductName模板列我們需要使用RequiredFieldValidator,而DetailsView的UnitPrice模板列也需要一個(gè)RequiredFieldValidator。此外,還需要給所有的UnitPrice模板列增加一個(gè)CompareValidator,以確保輸入的價(jià)格大于等于0并且是有效的貨幣格式。
注意:ASP.NET 1.x中已經(jīng)包含了這幾個(gè)驗(yàn)證控件,但是ASP.NET 2.0中增加了一些改進(jìn),主要的兩點(diǎn)是客戶端腳本對(duì)非IE瀏覽器的支持和對(duì)頁面上的部分驗(yàn)證控件進(jìn)行分組實(shí)現(xiàn)某個(gè)按鈕的特定驗(yàn)證控件組,參閱《Dissecting the Validation Controls in ASP.NET 2.0》(譯者:也可參閱MSDN http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnvs05/html/ValGroups.asp)。
現(xiàn)在我們來給GridView模板列中的EditItemTemplate增加這些要用到的驗(yàn)證控件。首先點(diǎn)擊GridView的智能標(biāo)記選擇編輯模板打開模板編輯界面,然后從下拉列表中選擇你要編輯的模板。由于我們要處理的是編輯界面,這里我們要給ProductName和UnitPrice的EditItemTemplate模板增加驗(yàn)證控件。
圖4:展開ProductName和UnitPrice的 EditItemTemplate模板
在ProductName的EditItemTemplate中,通過拖拉方式從工具箱里給編輯界面增加一個(gè)RequiredFieldValidator,放在TextBox后面。
圖5:為ProductName的EditItemTemplate增加一個(gè)RequiredFieldValidator
所有的驗(yàn)證控件都只能為單個(gè)ASP.NET Web控件服務(wù),因此,需要讓新增的這個(gè)驗(yàn)證控件為EditItemTemplate的TextBox控件進(jìn)行驗(yàn)證;這需要將要驗(yàn)證控件的ID設(shè)置給驗(yàn)證控件的 ControlToValidate property屬性。TextBox當(dāng)前的ID可能是一個(gè)莫明的TextBox1,我們最好還是賦予它一個(gè)更合適的ID,單擊模板中的TextBox,按F4查看屬性窗口,將ID由TextBox1改為EditProductName。
圖6:將TextBox的ID改名為 EditProductName
接下來,設(shè)置RequiredFieldValidator的ControlToValidate屬性為EditProductName。最后,設(shè)置ErrorMessage屬性為“You must provide the product's name” 并將Text屬性設(shè)置為“*”。如果設(shè)置了Text屬性,那么當(dāng)驗(yàn)證失敗的時(shí)候文本值就會(huì)被顯示出來。ErrorMessage屬性也是必須的,它是為ValidationSummary準(zhǔn)備的;當(dāng)Text屬性值被省略時(shí),ErrorMessage屬性也會(huì)在無效輸入時(shí)作為文本顯示出來。
設(shè)置完RequiredFieldValidator的這些屬性后,屏幕應(yīng)該如圖7所示:
圖7:設(shè)置RequiredFieldValidator控件的 ControlToValidate, ErrorMessage和Text 屬性
為ProductName的EditItemTemplate增加完RequiredFieldValidator,余下的就是為UnitPrice的EditItemplate模板增加一些必要的驗(yàn)證控件。由于我們決定UnitPrice編輯時(shí)作為選填,所以并不需要RequiredFieldValidator。不過需要增加一個(gè)CompareValidator來確保UnitPrice 有效,必須大于等于0并且時(shí)貨幣格式。
在為UnitPrice 的EditItemTemplate模板增加CompareValidator之前,先將TextBox的ID改為EditUnitPrice。然后添加CompareValidator控件并設(shè)置 ControlToValidate屬性為EditUnitPrice,ErrorMessage屬性為“The price must be greater than or equal to zero and cannot include the currency symbol”,Text 屬性為 “*”。
為了確保UnitPrice值必須大于等于0,設(shè)置CompareValidator的Operator屬性為GreaterThanEqual,ValueToCompare屬性為 “0”, 并且Type屬性為Currency。下面的代碼顯示了UnitPrice 模板列中的 EditItemTemplate調(diào)整后的樣子:
<EditItemTemplate> <asp:TextBox ID="EditUnitPrice" runat="server" Text='<%# Bind("UnitPrice", "{0:c}") %>' Columns="6"></asp:TextBox> <asp:CompareValidator ID="CompareValidator1" runat="server" ControlToValidate="EditUnitPrice"ErrorMessage="The price must be greater than or equal to zero and cannot include the currency symbol"Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0">*</asp:CompareValidator> </EditItemTemplate>
這些調(diào)整之后,在瀏覽器里查看這個(gè)頁面。如果對(duì)product編輯時(shí)你嘗試省略name或者輸入一個(gè)無效的price,星號(hào)就會(huì)顯示在文本框后面。如圖8顯示,包含了貨幣符合的price,如$19.95,將被視作無效。CompareValidator控件的Currency類型允許數(shù)字分割符(像逗號(hào),小數(shù)點(diǎn),取決于culture設(shè)置),以正負(fù)號(hào)開頭,但是不允許貨幣符號(hào)。而編輯界面UnitPrice卻呈現(xiàn)為貨幣形式,這種行為可能令用戶很困惑。
注意:回想一下《研究插入、更新和刪除的關(guān)聯(lián)事件》教程,我們?cè)O(shè)置了綁定列的DataFormatString屬性為{0:c},使其格式化為貨幣。由于我們將ApplyFormatInEditMode屬性置為true,導(dǎo)致 GridView編輯界面將UnitPrice格式化為貨幣格式。當(dāng)綁定列轉(zhuǎn)換為模板列會(huì)保留這些設(shè)置并且對(duì)TextBox的Text屬性使用綁定語法<%# Bind("UnitPrice", "{0:c}") %>進(jìn)行格式化。
圖8:無效輸入時(shí)文本框后面顯示的星號(hào)
基于如此的驗(yàn)證方式,在編輯記錄時(shí)用戶必須手動(dòng)刪除貨幣符號(hào),很難讓人接受。下面有三種選擇進(jìn)行補(bǔ)救:
1. 配置EditItemTemplate使 UnitPrice不會(huì)被格式化為貨幣。
2. 移除CompareValidator并替換為RegularExpressionValidator,允許用戶輸入貨幣符號(hào),但是要編寫代碼來適應(yīng)不同的文化設(shè)置。
3. 移除驗(yàn)證控件并在GridView的RowUpdating事件處理中進(jìn)行服務(wù)器端驗(yàn)證邏輯。
我們這里采用第一種方式。UnitPrice通過EditItemTemplate中的綁定表達(dá)式<%# Bind("UnitPrice", "{0:c}") %>轉(zhuǎn)換為貨幣格式。將其改為Bind("UnitPrice", "{0:n2}")格式化為兩位小數(shù)的數(shù)字。這些操作可以直接在元素標(biāo)記里完成,也可以通過點(diǎn)擊EditUnitPrice文本框的‘編輯 DataBindings…'鏈接(見圖9、圖10)
圖9:點(diǎn)擊TextBox的‘編輯 DataBindings'鏈接
圖10:為綁定表達(dá)式指定特定格式
這些改變之后,編輯界面的price被格式化為含義逗號(hào)和小數(shù)點(diǎn)的格式,卻沒有了貨幣符號(hào)。
注意: UnitPrice的 EditItemTemplate 不包含 RequiredFieldValidator, 運(yùn)行回傳并繼續(xù)更新邏輯。然而,《研究插入、更新和刪除的關(guān)聯(lián)事件》教程中拷過來的RowUpdating 事件處理包含了對(duì)提供的UnitPrice的檢查代碼。刪除邏輯,保持原樣,或者給UnitPrice的EditItemTemplate增加RequiredFieldValidator 悉隨尊便。
四:概述頁上的數(shù)據(jù)錄入問題
除了這5個(gè)驗(yàn)證控件之外,ASP.NET包含了一個(gè)總結(jié)控件ValidationSummary control,可以顯示那些檢測(cè)到無效數(shù)據(jù)的驗(yàn)證控件的ErrorMessage。以文本方式在頁上某個(gè)位置概述錯(cuò)誤結(jié)果,或者通過一個(gè)客戶端消息框。下面我們?yōu)槌绦蛟黾右粋€(gè)客戶端消息框概述頁上全部的驗(yàn)證問題。
從工具箱拖一個(gè)ValidationSummary控件到設(shè)計(jì)窗口上,它的位置沒什么要求,因?yàn)槲覀兇蛩惆阉韵⒖虻男问斤@示。在增加控件完之后,設(shè)置其ShowSummary屬性為false并設(shè)置ShowMessageBox屬性為true。這樣以來,所有的驗(yàn)證錯(cuò)誤都會(huì)顯示在一個(gè)客戶端消息框中。
圖11:客戶端消息框中的驗(yàn)證錯(cuò)誤總結(jié) (點(diǎn)擊放大)
五、為DetailsView的InsertItemTemplate增加驗(yàn)證控件
本教程中余下的部分就是為DetailsView的新增界面增加驗(yàn)證控件。這一工作與第三小節(jié)一樣,這里不再贅言。像GridView的EditItemTemplates 操作中提到的,推薦重命名TextBox的ID,這里分別使用InsertProductName 和 InsertUnitPrice而不是TextBox1 和 TextBox2。
為ProductName的 InsertItemTemplate增加RequiredFieldValidator驗(yàn)證控件,并設(shè)置其ControlToValidate 為模板中TextBox的ID, 設(shè)置Text 屬性為 “*” ,ErrorMessage 屬性為 “You must provide the product's name”。
由于頁面上的UnitPrice對(duì)于新增記錄是必填項(xiàng),所以我們?cè)赨nitPrice的 InsertItemTemplate中為其增加RequiredFieldValidator,設(shè)置ControlToValidate, Text和ErrorMessage 等相關(guān)屬性。最后,在UnitPrice 的InsertItemTemplate增加適當(dāng)?shù)腃ompareValidator,參照前面UnitPrice增加 CompareValidator的情形配置其ControlToValidate, Text, ErrorMessage, Type, Operator和 ValueToCompare等相關(guān)屬性。
通過增加的這些驗(yàn)證控件,新的product如果不提供name或者price為負(fù)數(shù)或者非法格式都會(huì)被系統(tǒng)拒絕添加。
圖12:DetailsView新增界面中添加的驗(yàn)證邏輯 (點(diǎn)擊放大)
六、對(duì)驗(yàn)證控件進(jìn)行分組
頁面上有兩套邏輯上獨(dú)立的驗(yàn)證控件集合: GridView的編輯界面和DetailsView新增界面上相應(yīng)的兩組。默認(rèn)情況下,當(dāng)postback發(fā)生時(shí)頁面上所有的驗(yàn)證都會(huì)生效。顯然,當(dāng)編輯記錄時(shí)我們不希望DetailsView新增功能的驗(yàn)證起作用,圖13說明了這種尷尬局面-當(dāng)用戶在編輯product時(shí)輸入了有些有效數(shù)據(jù),在點(diǎn)擊更新時(shí)卻由于新增功能中的name和price空白而產(chǎn)生驗(yàn)證錯(cuò)誤。
圖13:更新Product引發(fā)新增功能的驗(yàn)證控件 (點(diǎn)擊放大)
ASP.NET 2.0中的驗(yàn)證控件可以進(jìn)行分組,這一功能是通過ValidationGroup屬性。為了將這些驗(yàn)證控件關(guān)聯(lián)到一個(gè)組,只需把ValidationGroup屬性指定成同一個(gè)值。本教程中,將GridView模板中的ValidationGroup屬性統(tǒng)一設(shè)置為EditValidationControls,而DetailsView模板中的 ValidationGroup屬性則為InsertValidationControls。上述操作可以直接在代碼編輯窗口完成或者通過設(shè)計(jì)器模板編輯界面的屬性窗口修改。
ASP.NET 2.0中除了驗(yàn)證控件,按鈕和按鈕相關(guān)控件也增加了ValidationGroup屬性。驗(yàn)證組中的驗(yàn)證控件只在有相同ValidationGroup屬性的按鈕產(chǎn)生 postback時(shí)才會(huì)進(jìn)行有效性檢測(cè),例如,為使DetailsView的新增按鈕可以觸發(fā)InsertValidationControls驗(yàn)證組,我們給CommandField的 ValidationGroup屬性指定為InsertValidationControls(圖14),而GridView中CommandField的ValidationGroup屬性則指定為 EditValidationControls。
圖14:設(shè)置DetailsView中CommandField的 ValidationGroup屬性為InsertValidationControls
上述操作后,DetailsView和GridView的模板TemplateFields 和 CommandFields大致如下:DetailsView中的TemplateField模板和CommandField模板:
<asp:TemplateField HeaderText="ProductName" SortExpression="ProductName"> <InsertItemTemplate> <asp:TextBox ID="InsertProductName" runat="server" Text='<%# Bind("ProductName") %>'></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="InsertProductName" ErrorMessage="You must provide the product name" ValidationGroup="InsertValidationControls">* </asp:RequiredFieldValidator> </InsertItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice"> <InsertItemTemplate> <asp:TextBox ID="InsertUnitPrice" runat="server" Text='<%# Bind("UnitPrice") %>' Columns="6"> </asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server" ControlToValidate="InsertUnitPrice" ErrorMessage="You must provide the product price" ValidationGroup="InsertValidationControls">* </asp:RequiredFieldValidator> <asp:CompareValidator ID="CompareValidator2" runat="server" ControlToValidate="InsertUnitPrice" ErrorMessage="The price must be greater than or equal to zero and cannot include the currency symbol" Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0" ValidationGroup="InsertValidationControls">* </asp:CompareValidator> </InsertItemTemplate> </asp:TemplateField> <asp:CommandField ShowInsertButton="True" ValidationGroup="InsertValidationControls" /> GridView中的CommandField模板和TemplateFields模板: <asp:CommandField ShowEditButton="True" ValidationGroup="EditValidationControls" /> <asp:TemplateField HeaderText="ProductName" SortExpression="ProductName"> <EditItemTemplate> <asp:TextBox ID="EditProductName" runat="server" Text='<%# Bind("ProductName") %>'> </asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="EditProductName" ErrorMessage="You must provide the product name" ValidationGroup="EditValidationControls">* </asp:RequiredFieldValidator> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Bind("ProductName") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="UnitPrice" SortExpression="UnitPrice"> <EditItemTemplate> <asp:TextBox ID="EditUnitPrice" runat="server" Text='<%# Bind("UnitPrice", "{0:n2}") %>' Columns="6"></asp:TextBox> <asp:CompareValidator ID="CompareValidator1" runat="server" ControlToValidate="EditUnitPrice" ErrorMessage="The price must be greater than or equal to zero and cannot include the currency symbol" Operator="GreaterThanEqual" Type="Currency" ValueToCompare="0" ValidationGroup="EditValidationControls">* </asp:CompareValidator> </EditItemTemplate> <ItemTemplate> <asp:Label ID="Label2" runat="server" Text='<%# Bind("UnitPrice", "{0:c}") %>'> </asp:Label> </ItemTemplate> </asp:TemplateField>
當(dāng)GridView的更新按鈕點(diǎn)擊時(shí),編輯中特定的驗(yàn)證控件將會(huì)開始檢測(cè),而當(dāng)DetailsView中的新增按鈕被點(diǎn)擊時(shí),新增功能的相關(guān)驗(yàn)證生效,圖13的高亮部分顯示了此舉解決的問題。但是這些改動(dòng)之后,輸入無效數(shù)據(jù)時(shí)ValidationSummary驗(yàn)證總結(jié)卻不再顯示了。這是由于 ValidationSummary控件也擁有ValidationGroup屬性并且只顯示來自于同一驗(yàn)證組中驗(yàn)證控件的信息。因此,我們需要使用兩個(gè)驗(yàn)證控件,分別作為InsertValidationControls驗(yàn)證組和EditValidationControls驗(yàn)證組:
<asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowMessageBox="True" ShowSummary="False" ValidationGroup="EditValidationControls" /> <asp:ValidationSummary ID="ValidationSummary2" runat="server" ShowMessageBox="True" ShowSummary="False" ValidationGroup="InsertValidationControls" />
寫到這里,本節(jié)教程就可以畫上句號(hào)了。
小結(jié)
雖然綁定列BoundField可以提供了新增/編輯界面,卻不能對(duì)其進(jìn)行定制。很多情況,我們要給新增/編輯增加驗(yàn)證功能以確保用戶輸入合法有效的數(shù)據(jù)。為此,我們將BoundFields轉(zhuǎn)換成了TemplateField,并在相應(yīng)模板中增加了驗(yàn)證控件。本節(jié)教程擴(kuò)展了《Examining the Events Associated with Inserting, Updating, and Deleting》中的代碼,為DetailsView的新增和GridView的編輯界面增加了驗(yàn)證功能。此外,還演示了如何使用ValidationSummary控件顯示驗(yàn)證總結(jié)以及如何對(duì)驗(yàn)證控件進(jìn)行分組。
正如本文所見,模板列允許為新增/編輯界面增加驗(yàn)證控件,當(dāng)然也可以擴(kuò)展其他的Web控件。在下節(jié)教程中,將會(huì)演示如何用可數(shù)據(jù)綁定的DropDownList控件替換原有的TextBox,僅僅通過一個(gè)外鍵(如Products表中的CategoryID或SupplierID)。
祝編程快樂!
作者簡(jiǎn)介
Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創(chuàng)始人,自1998年以來一直應(yīng)用微軟Web技術(shù)。Scott是個(gè)獨(dú)立的技術(shù)咨詢顧問,培訓(xùn)師,作家,最近完成了將由Sams出版社出版的新作, 《24小時(shí)內(nèi)精通ASP.NET 2.0》(英文) 。 他的聯(lián)系電郵為mitchell@4guysfromrolla.com,也可以通過他的博客http://scottonwriting.net/與他聯(lián)系。
- ASP.NET表單驗(yàn)證方法詳解
- asp.net 繼承自Page實(shí)現(xiàn)統(tǒng)一頁面驗(yàn)證與錯(cuò)誤處理
- asp.net MaxLengthValidator 最大長(zhǎng)度驗(yàn)證控件代碼
- jQuery 驗(yàn)證插件 Web前端設(shè)計(jì)模式(asp.net)
- ASP.net的驗(yàn)證控件淺析
- ASP.NET MVC5添加驗(yàn)證(4)
- ASP.NETWeb服務(wù)器驗(yàn)證控件如何使用
- ASP.NET中HTML頁面的訪問驗(yàn)證設(shè)置方法
- 詳解ASP.NET MVC Form表單驗(yàn)證
- ASP.NET中Validation驗(yàn)證控件正則表達(dá)式特殊符號(hào)的說明
- 在ASP.NET 2.0中操作數(shù)據(jù)之三十九:在DataList的編輯界面里添加驗(yàn)證控件
相關(guān)文章
NopCommerce架構(gòu)分析之(五)Model綁定Action參數(shù)
本文主要介紹NopCommerce中在請(qǐng)求Controller的Action方法前,通過ModelBinder將Model進(jìn)行綁定,以便后續(xù)捕捉到數(shù)據(jù),轉(zhuǎn)化成對(duì)象,再進(jìn)行處理。2016-04-04ASP.NET MVC4入門教程(六):驗(yàn)證編輯方法和編輯視圖
本文主要演示如何修改控制器和視圖以及處理POST的請(qǐng)求,以達(dá)到實(shí)現(xiàn)我們想要的功能。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之七十二:調(diào)試存儲(chǔ)過程
在開發(fā)過程中,使用Visual Studio的斷點(diǎn)調(diào)試功能可以很方便幫我們調(diào)試發(fā)現(xiàn)程序存在的錯(cuò)誤,同樣Visual Studio也支持對(duì)SQL Server里面的存儲(chǔ)過程進(jìn)行調(diào)試,下面就讓我們看看具體的調(diào)試方法。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之六:編程設(shè)置ObjectDataSource的參數(shù)值
本文主要介紹在ObjectDataSource控件的Selecting事件中,設(shè)置InputParameters參數(shù),配合業(yè)務(wù)層的查詢方法,以達(dá)到查詢不同數(shù)據(jù)的目的。2016-04-04解讀ASP.NET 5 & MVC6系列教程(8):Session與Caching
這篇文章主要介紹了ASP.NET 5 中的Session與Caching配置和使用,需要的朋友可以參考下2016-06-06在ASP.NET 2.0中操作數(shù)據(jù)之六十六:在TableAdapters中使用現(xiàn)有的存儲(chǔ)過程
雖然通過TableAdapter向?qū)Э梢宰詣?dòng)的生成存儲(chǔ)過程,但是在某些時(shí)候我們需要使用現(xiàn)有的存儲(chǔ)過程。本文將講解如何在Visual Studio環(huán)境里手動(dòng)添加存儲(chǔ)過程,并引導(dǎo)TableAdapter的方法使用這些存儲(chǔ)過程。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之四十四:DataList和Repeater數(shù)據(jù)排序(三)
上篇已經(jīng)完成了自定義分頁,這一節(jié)我們繼續(xù)完善排序功能。2016-05-05在ASP.NET 2.0中操作數(shù)據(jù)之六十三:GridView實(shí)現(xiàn)批量刪除數(shù)據(jù)
本文主要介紹在GridView控件中包含一個(gè)checkbox列來實(shí)現(xiàn)復(fù)選多條數(shù)據(jù),在批量刪除按鈕的事件中通過for循環(huán)來一一刪除。2016-05-05《解剖PetShop》之二:PetShop數(shù)據(jù)訪問層數(shù)之據(jù)庫訪問設(shè)計(jì)
本文主要講解PetShop4.0的數(shù)據(jù)訪問層設(shè)計(jì),包括:數(shù)據(jù)庫訪問、Messaging、MemberShip、Profile四部分,需要的朋友可以參考下。2016-05-05