亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七::

系統(tǒng) 2110 0

導(dǎo)言

當(dāng)使用 GridView DetailsView FormView 控件的內(nèi)建插入、編輯或刪除特征時(shí),在用戶添加一條新記錄或更新 / 刪除一條現(xiàn)在記錄的過(guò)程中發(fā)生了多個(gè)步驟。正如我們之前一節(jié)里所討論的,在 GridView 中編輯一行時(shí),保存( Update )和取消( Cancel )按鈕將取代編輯( Edit )按鈕,并且綁定列轉(zhuǎn)換成 TextBox 。在用戶更新了數(shù)據(jù)并點(diǎn)擊保存按鈕之后,下述步驟在回傳時(shí)執(zhí)行:

1. GridView 控件根據(jù)當(dāng)前編輯行的唯一標(biāo)識(shí)字段(通過(guò) DataKeyNames 屬性)組裝它的 ObjectDataSource UpdateParameters 參數(shù),連同用戶輸入的值

2. GridView 控件調(diào)用它的 ObjectDataSource Update() 方法,它轉(zhuǎn)而調(diào)用潛在對(duì)象的適當(dāng)?shù)姆椒ǎ? ProductsDAL.UpdateProduct ,我們之前一節(jié)里)

3. 現(xiàn)在,這些隱含的數(shù)據(jù),包含保存后的更改,被重新綁定到 GridView 控件

在這一連串的步驟里,觸發(fā)了許多事件,這讓我們可以創(chuàng)建事件處理程序從而在需要的地方增加自定義邏輯。例如,在第 1 步之前,觸發(fā) GridView 的事件。在這里,如果有什么 validation 錯(cuò)誤我們可以取消更新請(qǐng)求。當(dāng)調(diào)用 Update() 方法時(shí),觸發(fā) ObjectDataSource Updating 事件,提供了增加或自定義 UpdateParameters 的值的機(jī)會(huì)。在 ObjectDataSource 的潛在對(duì)象的方法完全執(zhí)行后,觸發(fā) ObjectDataSource Updated 事件。針對(duì) Updated 事件的事件處理程序可以檢查更新操作的相關(guān)詳細(xì)信息,例如影響了多少行數(shù)據(jù),或者是否引發(fā)了一個(gè)異常。最后,在第 2 步之后, GridView RowUpdated 事件觸發(fā);針對(duì)此事件的事件處理程序可以檢查關(guān)于剛剛完成的更新操作的相關(guān)額外信息。

1 描述了使用 GridView 更新時(shí)這一系列連續(xù)的事件和步驟。圖 1 里的這個(gè)事件模式不僅是在 GridView 的更新操作。從 GridView DetailsView 或者 FormView 里插入、更新或者刪除數(shù)據(jù)時(shí),數(shù)據(jù) Web 服務(wù)器控件和 ObjectDataSource 都會(huì)發(fā)生這一連串的 pre-level post-level 的事件。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
1: 當(dāng)在 GridView 里更新數(shù)據(jù)時(shí),觸發(fā)一連串的 Pre- Post- 事件

在這一節(jié)里,我們將探討使用這些事件從而擴(kuò)展 ASP.NET 數(shù)據(jù) Web 服務(wù)器控件的內(nèi)建插入、更新和刪除功能。我們也會(huì)看看如何自定義編輯界面從而僅僅更新部分產(chǎn)品字段。

第一步 : 更新產(chǎn)品的 ProductName UnitPrice 字段

在之前一節(jié)的編輯界面里,包含了產(chǎn)品的所有字段并且它們都不是只讀的。如果我們從 GridView 中剔除一列( QuantityPerUnit ),那么當(dāng)更新時(shí)數(shù)據(jù) Web 服務(wù)器控件就不會(huì)設(shè)置 ObjectDataSource QuantityPerUnit UpdateParameters 的值。 ObjectDataSource 則傳入一個(gè) null 值到 UpdateProduct 這個(gè)業(yè)務(wù)邏輯層的方法,它將當(dāng)前編輯的數(shù)據(jù)庫(kù)記錄的 QuantityPerUnit 字段更改為值。同樣地,如果是一個(gè)必需的字段,例如 ProductName ,如果從編輯界面中剔除了,那么此更新將會(huì)失敗并拋出一個(gè) Column 'ProductName' does not allow nulls 異常。導(dǎo)致這一現(xiàn)象的原因是 ObjectDataSource 被配置為調(diào)用 ProductsBLL 類的 UpdateProduct 方法,它預(yù)期每一個(gè)產(chǎn)品字段都對(duì)應(yīng)一個(gè)輸入?yún)?shù)。因此, ObjectDataSource UpdateParameters 集合包含了該方法的每一個(gè)輸入?yún)?shù)。

如果我們希望提供一個(gè)允許最終用戶僅僅可以更新部分字段的數(shù)據(jù) Web 服務(wù)器控件,那么我們需要在 ObjectDataSource Updating 事件處理程序中編程設(shè)置缺失的 UpdateParameters 值,或者創(chuàng)建并調(diào)用一個(gè)預(yù)期部分字段的 BLL 方法。讓我們?cè)诮酉聛?lái)的步驟中探討。

特別地,讓我們創(chuàng)建一個(gè)在一個(gè)可編輯的 GridView 中僅顯示 ProductName UnitPrice 字段的頁(yè)面。這個(gè) GridView 的編輯界面將僅僅允許用戶更新兩個(gè)顯示的字段, ProductName UnitPrice 。因?yàn)檫@個(gè)編輯界面僅僅提供產(chǎn)品的部分字段,我們需要?jiǎng)?chuàng)建一個(gè) ObjectDataSource ,它使用現(xiàn)有的 BLL UpdateProduct 方法并在 Updating 事件處理程序中編程設(shè)置產(chǎn)品的缺少的字段的值,或者我們需要?jiǎng)?chuàng)建一個(gè)新的 BLL 方法,它僅接受那些在 GridView 中已經(jīng)定義的部分字段。在這一節(jié)里,我們使用后者,創(chuàng)建一個(gè) UpdateProduct 方法的重載,它提取 3 個(gè)輸入?yún)?shù): productName unitPrice productID

[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, false)]

public bool UpdateProduct(string productName, decimal? unitPrice, int productID)

{

Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);

if (products.Count == 0)

// no matching record found, return false

return false;

Northwind.ProductsRow product = products[0];

product.ProductName = productName;

if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value;

// Update the product record

int rowsAffected = Adapter.Update(product);

// Return true if precisely one row was updated, otherwise false

return rowsAffected == 1;

}

跟原有的 UpdateProduct 方法類似,這個(gè)重載方法首先檢查是否在數(shù)據(jù)庫(kù)中存在一個(gè)指定 ProductID 的產(chǎn)品。如果不存在,它返回 false ,指示更新產(chǎn)品信息的請(qǐng)求失敗。否則,它因而更新現(xiàn)存的產(chǎn)品記錄的 ProductName UnitPrice 字段并通過(guò)調(diào)用 TableAdapter Update() 方法提交此更新,傳入 ProductsRow 實(shí)例。

通過(guò)這些對(duì)我們的 ProductsBLL 類的額外處理,我們現(xiàn)在可以創(chuàng)建一個(gè)簡(jiǎn)單 GridView 界面。打開(kāi) EditInsertDelete 文件夾中的 DataModificationEvents.aspx ,添加一個(gè) GridView 控件到頁(yè)面。新建一個(gè) ObjectDataSource 并配置它使用 ProductsBLL 類,它的 Select() 方法映射到 GetProducts Update() 方法映射到僅接受 productName unitPrice productID 輸入?yún)?shù)的 UpdateProduct 方法重載。圖 2 展示了映射 ObjectDataSource Update() 方法到 ProductsBLL 類的新的 UpdateProduct 方法重載時(shí)的數(shù)據(jù)源配置向?qū)А?

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
2: 映射 ObjectDataSource Update() 方法到新的 UpdateProduct 重載

因?yàn)槲覀兊睦訉H僅需要編輯數(shù)據(jù)的能力,不需要插入或刪除記錄,那么花些時(shí)間明確地指明該 ObjectDataSource Insert() Delete() 方法不會(huì)映射到 ProductsBLL 類的任何方法 -- 通過(guò)到 INSERT DELETE tab 頁(yè)并從下拉列表中選擇(無(wú))。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
3: INSERT DELETE Tab 頁(yè),從下拉列表中選擇(無(wú))

完成了此向?qū)Ш螅瑥? GridView 的職能標(biāo)記里勾選上啟用編輯。

完成了此數(shù)據(jù)源配置向?qū)Р⒔壎ǖ? GridView 后, Visual Staudio 就已經(jīng)添加好它們的聲明語(yǔ)法。到源視圖察看該 ObjectDataSource 的聲明標(biāo)記,它將如下所示:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts" TypeName="ProductsBLL" UpdateMethod="UpdateProduct">

<UpdateParameters>

<asp:Parameter Name="productName" Type="String" />

<asp:Parameter Name="unitPrice" Type="Decimal" />

<asp:Parameter Name="productID" Type="Int32" />

</UpdateParameters>

</asp:ObjectDataSource>

因?yàn)? ObjectDataSource Insert() Delete() 方法沒(méi)有映射,也就沒(méi)有 InsertParameters 或者 DeleteParameters 片段。此外,因?yàn)榉椒ㄓ成涞? UpdateProduct 方法重載,它僅接受 3 個(gè)輸入?yún)?shù), UpdateParameters 片段也就僅包含 3 個(gè) Parameter 實(shí)例。

注意到 ObjectDataSource 的屬性被設(shè)置為 original_{0} 。這個(gè)屬性是使用數(shù)據(jù)源配置向?qū)r(shí) Visual Studio 自動(dòng)設(shè)置的。因此,由于我們的 BLL 方法不需要傳入原始的 ProductID 值,從 ObjectDataSource 的聲明語(yǔ)法中刪除所有這些屬性設(shè)置。

注意 : If you 如果你只是簡(jiǎn)單地在設(shè)計(jì)視圖里從屬性窗口清除 OldValuesParameterFormatString 屬性的值,這個(gè)屬性會(huì)依舊存在于聲明語(yǔ)法里,但會(huì)被設(shè)置為一個(gè)空字符串。要么從聲明語(yǔ)法里把該屬性通通刪掉,要么從屬性窗口,設(shè)置它的值為默認(rèn)值: {0}

雖然 ObjectDataSource 僅僅包含對(duì) productName unitPrice productID UpdateParameters Visual Studio 還是為產(chǎn)品的每一個(gè)字段添加一個(gè)綁定列或 CheckBoxField

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
4: 對(duì)應(yīng)產(chǎn)品的每一個(gè)字段, GridView 都包含一個(gè) BoundField CheckBoxField

當(dāng)最終用戶編輯一個(gè)產(chǎn)品并點(diǎn)擊它的保存按鈕( Update ),該 GridView 遍歷那些可編輯的字段,然后把用戶輸入的值賦值到 ObjectDataSource UpdateParameters 集合里對(duì)應(yīng)的參數(shù)。如果沒(méi)有對(duì)應(yīng)的參數(shù), GridView 則添加一個(gè)到參數(shù)集合里。因此,如果我們的 GridView 包含對(duì)應(yīng)產(chǎn)品的所有字段的綁定列或 CheckBox 列,那么 ObjectDataSource 則會(huì)調(diào)用能接受這些參數(shù)的方法重載,而不顧 ObjectDataSource 的聲明標(biāo)記指定只接受 3 個(gè)輸入?yún)?shù)的事實(shí)(見(jiàn)圖 5 )。類似地,如果存在某些由 GridView 非只讀列構(gòu)成的組合,而沒(méi)有一個(gè) UpdateProduct 重載能接受相應(yīng)的參數(shù),則會(huì)在試圖保存時(shí)引發(fā)一個(gè)異常。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
5: GridView 將添加參數(shù)到 ObjectDataSource UpdateParameters 集合

為了確保 ObjectDataSource 調(diào)用僅接受 productName unitPrice productID 參數(shù) UpdateProduct 重載,我們需要限定 GridView 僅包含 ProductName UnitPrice 這兩個(gè)可編輯的列。這可以通過(guò)刪除其他綁定列和 CheckBox 列,或者把這些列的 ReadOnly 屬性設(shè)置為 true 實(shí)現(xiàn),又或者上述兩種方法結(jié)合使用。在本節(jié)里讓我們簡(jiǎn)單地刪除除了 ProductName UnitPrice 綁定列以外的 GridView 的所有列,然后, GridView 的聲明標(biāo)記將如下所示:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">

<Columns>

<asp:CommandField ShowEditButton="True" />

<asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />

<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" />

</Columns>

</asp:GridView>

即使重載預(yù)期 3 個(gè)輸入?yún)?shù),在我們的 GridView 里僅包含兩個(gè)綁定列。這是因?yàn)? productID 輸入?yún)?shù)是一個(gè)主鍵( primary key )的值,它通過(guò)當(dāng)前編輯行的 DataKeyNames 屬性傳入值。

我們的 GridView 控件,連同這個(gè) UpdateProduct 重載,允許一個(gè)用戶僅僅編輯產(chǎn)品的名稱和單價(jià)而不會(huì)丟失產(chǎn)品的其他字段。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
6: 僅允許編輯 ProductName Unit Price 的界面

完善 UnitPrice 格式化

雖然圖 6 所示的 GridView 實(shí)例能夠正常工作, UnitPrice 字段還完全未被格式化,導(dǎo)致顯示價(jià)格時(shí)缺少貨幣符號(hào),還有 4 個(gè)小數(shù)位。為了在非編輯狀態(tài)的行應(yīng)用貨幣格式,只需要簡(jiǎn)單地設(shè)置 UnitPrice 綁定列的 DataFormatString 屬性為 {0:c} ,還有它的 HtmlEncode 屬性為 false

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
7: 設(shè)置 UnitPrice 綁定列的 DataFormatString HtmlEncode 屬性

通過(guò)此項(xiàng)更改,處于非編輯狀態(tài)的行將價(jià)格格式化為貨幣;然而,當(dāng)前編輯的行,仍然顯示為沒(méi)有貨幣符號(hào)并保留四位小數(shù)。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
8: 現(xiàn)在,非編輯狀態(tài)的行格式化為貨幣值

通過(guò)設(shè)置此綁定列的 ApplyFormatInEditMode 屬性為 true (默認(rèn)為 false ),可以把 DataFormatString 屬性里指定的格式化指令應(yīng)用到編輯界面。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
9: 設(shè)置此綁定列的 ApplyFormatInEditMode 屬性為 true

通過(guò)這個(gè)更改,當(dāng)前編輯行里顯示的 UnitPrice 值也被格式化為貨幣。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
10: 現(xiàn)在,當(dāng)前編輯行的值也被格式化為貨幣

然而,如果把產(chǎn)品價(jià)格更新為文本框里帶貨幣符號(hào)的值 例如 $19.00 – 則會(huì)拋出一個(gè) FormatException 異常。當(dāng) GridView 嘗試把用戶提供的值賦值到 ObjectDataSource UpdateParameters 集合,它無(wú)法把 UnitPrice 字符串“ $<chmetcnv w:st="on" unitname="”" sourcevalue="19" hasspace="False" negative="False" numbertype="1" tcsc="0">19.00<span><span>”</span></span></chmetcnv> 轉(zhuǎn)換成參數(shù)要求的 decimal 類型(見(jiàn)圖 11 )。為了補(bǔ)救這個(gè)問(wèn)題我們可以為 GridView RowUpdating 事件添加一個(gè)事件處理程序并讓它把用戶輸入的 UnitPrice 格式化為貨幣格式的 decimal

這個(gè) GridView RowUpdating 事件接受的第二個(gè)參數(shù)是一個(gè) GridViewUpdateEventArgs 類型的對(duì)象,它包含一個(gè) NewValues 字典,當(dāng)中的每一個(gè)屬性保存著用戶輸入的值,準(zhǔn)備賦值到 ObjectDataSource UpdateParameters 集合。我們可以重寫(xiě)現(xiàn)有的 NewValues 集合中的 UnitPrice 值為一個(gè)貨幣金額,通過(guò)下面的事件處理程序中的代碼進(jìn)行解析:

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)

{

if (e.NewValues["UnitPrice"] != null)

e.NewValues["UnitPrice"] = decimal.Parse(e.NewValues["UnitPrice"].ToString(), System.Globalization.NumberStyles.Currency);

}

如果用戶提供了一個(gè)諸如“ $<chmetcnv w:st="on" unitname="”" sourcevalue="19" hasspace="False" negative="False" numbertype="1" tcsc="0">19.00<span><span>”</span></span></chmetcnv> UnitPrice 值,這個(gè)值會(huì)被通過(guò) Decimal.Parse 計(jì)算并解析為貨幣金額的值重寫(xiě)。這將正確的解析貨幣值,無(wú)論是貨幣符號(hào)、逗號(hào)、小數(shù)點(diǎn)、等等,并使用 System.Globalization 命名空間的 NumberStyles 枚舉

11 展示因用戶輸入的 UnitPrice 值帶有貨幣符號(hào)引起的問(wèn)題,還展示了如果利用 GridView RowUpdating 事件處理程序從而正確地解析這樣的輸入。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
11: 現(xiàn)在,當(dāng)前編輯行的 UnitPrice 值被格式化為貨幣金額

第二步 : 阻止 NULL UnitPrices

雖然數(shù)據(jù)庫(kù)被配置為允許 Products 表里的 UnitPrice 字段為 NULL 值,但我們可能希望防止用戶訪問(wèn)這個(gè)特別的頁(yè)面并指定一個(gè)空的 UnitPrice 值。更確切地說(shuō),如果用戶在編輯一個(gè)產(chǎn)品行記錄時(shí)忘記輸入一個(gè) UnitPrice 值, 與其保存這個(gè)結(jié)果到數(shù)據(jù)庫(kù),我們還不如給用戶顯示一個(gè)提示信息,自始至終這個(gè)頁(yè)面,任何的對(duì)產(chǎn)品的編輯必須指定一個(gè)價(jià)格。

傳入到 GridView 的事件處理程序的 GridViewUpdateEventArgs 對(duì)象包含一個(gè) Cancel 屬性,如果把它設(shè)置為 true ,則中止這個(gè)更新過(guò)程。讓我們擴(kuò)展 RowUpdating 事件處理程序,設(shè)置 e.Cancel true 并顯示一個(gè)信息說(shuō)明為什么在 NewValues 集合里的 UnitPrice 值為 null

首先,添加一個(gè) Label 服務(wù)器控件到頁(yè)面并命名為 MustProvideUnitPriceMessage 。這個(gè) Label 控件將顯示用戶是否在更新一個(gè)產(chǎn)品時(shí)忘記指定一個(gè) UnitPrice 值。設(shè)置這個(gè) Label Text 屬性為“您必須為產(chǎn)品提供一個(gè)價(jià)格。”。我也已經(jīng)在 Styles.css 文件中添加了一個(gè)名為 Warning 的新 CSS 類別,定義如下:

.Warning

{

color: Red;

font-style: italic;

font-weight: bold;

font-size: x-large;

}

最后,設(shè)置 Label CssClass 屬性為 Warning 。這樣設(shè)計(jì)器中將在 GridView 上方顯示這個(gè)紅色、斜體、加粗、并且較大字體的警告信息。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
12: 一個(gè) Label 控件已被添加到 GridView 上方

默認(rèn)地,這個(gè) Label 控件隱藏,那么在 Page_Load 事件處理程序中設(shè)置它的 Visible 屬性為 false

protected void Page_Load(object sender, EventArgs e)

{

MustProvideUnitPriceMessage.Visible = false;

}

如果用戶嘗試更新一個(gè)產(chǎn)品并不指定 UnitPrice 值,我們希望取消這個(gè)更新并顯示警告標(biāo)簽。在 GridView RowUpdating 事件處理程序中增加如下的代碼:

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)

{

if (e.NewValues["UnitPrice"] != null)

e.NewValues["UnitPrice"] = decimal.Parse(e.NewValues["UnitPrice"].ToString(), System.Globalization.NumberStyles.Currency);

else

{

// Show the Label

MustProvideUnitPriceMessage.Visible = true;

// Cancel the update

e.Cancel = true;

}

}

如果一個(gè)用戶試圖保存一個(gè)產(chǎn)品并不指定價(jià)格,這個(gè)更新操作就被取消并顯示一個(gè)有用的提示信息。雖然數(shù)據(jù)庫(kù)(和業(yè)務(wù)邏輯)允許 NULL 值的 UnitPrice ,但這個(gè)特定的 ASP.NET 頁(yè)面不允許。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
13: 用戶不能讓 UnitPrice 為空

到目前為止我們看過(guò)了如何使用 GridView RowUpdating 事件來(lái)編程改變賦值到 ObjectDataSource UpdateParameters 集合的參數(shù)值,還有如何完全地取消這個(gè)更新過(guò)程。這些思想也可以延展至 DetailsView FormView 控件并且應(yīng)用到插入或刪除。

這些任務(wù)也可以在 ObjectDataSource 這一層通過(guò)的 Inserting Updating Deleting 事件處理程序完成。這些事件在隱含對(duì)象的關(guān)聯(lián)方法被調(diào)用前觸發(fā),并且提供一個(gè)更改輸入?yún)?shù)集合或者完全取消此操作的最后機(jī)會(huì)。對(duì)應(yīng)這 3 個(gè)事件的事件處理程序傳入一個(gè) ObjectDataSourceMethodEventArgs 類型的對(duì)象,我們對(duì)它的這兩個(gè)屬性感興趣:

· Cancel ,它如果被設(shè)置為 true ,取消執(zhí)行中的操作

· InputParameters ,它是 InsertParameters UpdateParameters DeleteParameters 的集合,這取決于這是 Inserting Updating 還是 Deleting 事件的事件處理程序

為了舉例說(shuō)明在 ObjectDataSource 這一層如何處理參數(shù)的值,讓我們?cè)陧?yè)面里包含一個(gè) DeailsView ,它允許用戶新增一個(gè)新的產(chǎn)品記錄。這個(gè) DetailsView 將用作提供一個(gè)快捷的方式添加一個(gè)新的產(chǎn)品記錄到數(shù)據(jù)庫(kù)。為了在新增產(chǎn)品時(shí)保持界面一致,我們僅允許用戶輸入 ProductName UnitPrice 字段。作為默認(rèn)值,這些在 DetailsView 的插入界面提供的值將被設(shè)置為一個(gè)數(shù)據(jù)庫(kù)的 NULL 值。不過(guò),我們可以使用 ObjectDataSource Inserting 事件注入不同的默認(rèn)值,正如我們馬上要看的。

第三步 : 提供一個(gè)添加新產(chǎn)品的界面

GridView 的上方,從工具箱里拖放一個(gè) DetailsView 控件到設(shè)計(jì)器,清空它的 Height Width 屬性,并將它綁定到頁(yè)面中已經(jīng)存在的 ObjectDataSource 。這將為產(chǎn)品的每一個(gè)字段添加一個(gè)綁定列或 CheckBox 列。因?yàn)槲覀兿M眠@個(gè) DetailsView 控件來(lái)添加新產(chǎn)品,我們需要從它的職能標(biāo)記里勾選啟用插入這一項(xiàng);然而并沒(méi)有這一項(xiàng),這是因?yàn)榇? ObjectDataSource Insert() 方法還沒(méi)有映射到 ProductsBLL 類的方法(回想起我們?cè)谂渲脭?shù)據(jù)源時(shí)設(shè)置了這個(gè)映射為(無(wú)) 見(jiàn)圖 3 )。

為了再次配置這個(gè) ObjectDataSource ,從它的職能標(biāo)記中選擇“配置數(shù)據(jù)源”的鏈接,載入向?qū)А5谝黄猎试S你更改 ObjectDataSource 綁定到的隱含對(duì)象;讓它依舊是 ProductsBLL 。下一屏列出從 ObjectDataSource 到隱含對(duì)象的方法的映射。盡管我們已經(jīng)明確地指定 Insert() Delete() 不映射到任何方法,然而如果你到 INSERT DELETE tab 頁(yè)你還是會(huì)看到那里有一個(gè)映射。這是因?yàn)? ProductsBLL AddProduct DeleteProduct 方法使用了 DataObjectMethodAttribute 指出它們分別是為 Insert() Delete() 服務(wù)的默認(rèn)的方法。因此, ObjectDataSource 向?qū)г诿看芜\(yùn)行時(shí)都會(huì)自動(dòng)地選擇它們,除非那里被明確地指定了一個(gè)別的值。

Insert() 方法依舊指向 AddProduct 方法,不過(guò)再次從 DELETE tab 頁(yè)的下拉列表中選擇“ ( 無(wú) ) ”。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
14: INSERT Tab 頁(yè)的下拉列表中選擇 AddProduct 方法
Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
15: DELETE Tab 頁(yè)的下拉列表中選擇 ( 無(wú) )

完成了這些更改后,該 ObjectDataSource 的聲明語(yǔ)法中將包含一個(gè) InsertParameters 集合,如下所示:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetProducts"

TypeName="ProductsBLL" UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating" InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">

<UpdateParameters>

<asp:Parameter Name="productName" Type="String" />

<asp:Parameter Name="unitPrice" Type="Decimal" />

<asp:Parameter Name="productID" Type="Int32" />

</UpdateParameters>

<InsertParameters>

<asp:Parameter Name="productName" Type="String" />

<asp:Parameter Name="supplierID" Type="Int32" />

<asp:Parameter Name="categoryID" Type="Int32" />

<asp:Parameter Name="quantityPerUnit" Type="String" />

<asp:Parameter Name="unitPrice" Type="Decimal" />

<asp:Parameter Name="unitsInStock" Type="Int16" />

<asp:Parameter Name="unitsOnOrder" Type="Int16" />

<asp:Parameter Name="reorderLevel" Type="Int16" />

<asp:Parameter Name="discontinued" Type="Boolean" />

</InsertParameters>

</asp:ObjectDataSource>

再次運(yùn)行向?qū)?dǎo)致重新添加 OldValuesParameterFormatString 屬性。把這個(gè)屬性設(shè)置為默認(rèn)值( {0} )或者從聲明語(yǔ)法中把它們完全刪除。

隨著 ObjectDataSource 提供插入數(shù)據(jù)的能力,現(xiàn)在 DetailsView 的職能標(biāo)記里包含“啟用插入”的 checkbox ;回到設(shè)計(jì)器并勾選這一項(xiàng)。然后,減少 DetailsView 的列直道它只包含兩個(gè)綁定列 - ProductName UnitPrice ,還有一個(gè) CommandField 。此時(shí) DetailsView 的聲明語(yǔ)法將如下所示:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">

<Fields>

<asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />

<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" SortExpression="UnitPrice" />

<asp:CommandField ShowInsertButton="True" />

</Fields>

</asp:DetailsView>

16 展現(xiàn)的是在此時(shí)通過(guò)瀏覽器查看的頁(yè)面。正如你所看到的, DetailsView 列出第一個(gè)產(chǎn)品( Chai )的名稱和價(jià)格。不過(guò),我們需要的是一個(gè)插入界面來(lái)提供一個(gè)用戶快速增加一個(gè)新產(chǎn)品到數(shù)據(jù)庫(kù)的手段。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
16: DetailsView 當(dāng)前呈現(xiàn)在只讀模式

為了展示插入模式的 DetailsView 我們需要設(shè)置 DefaultMode 屬性為 Inserting 。這讓 DetailsView 在第一次訪問(wèn)和插入一條新紀(jì)錄之后,它都呈現(xiàn)在插入模式。如圖 17 所示,這樣的一個(gè) DetailsView 提供了一個(gè)快捷的界面用以添加新記錄。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
17: 這個(gè) DetailsView 提供了一個(gè)快速添加新產(chǎn)品的界面

當(dāng)用戶輸入一個(gè)產(chǎn)品名稱和價(jià)格(例如“ Acme Wate ”和 1.99 ,如圖 17 )并點(diǎn)擊插入按鈕,發(fā)生回傳并且開(kāi)始插入的工作流程,直到最后添加一個(gè)新產(chǎn)品記錄到數(shù)據(jù)庫(kù)。 DetailsView 維持在它的插入界面,并且 GridView 自動(dòng)地重現(xiàn)綁定到它的數(shù)據(jù)源,目的是為了包含新增加的產(chǎn)品,如圖 18 所示。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
18: 產(chǎn)品“ Acme Water ”已經(jīng)被添加到數(shù)據(jù)庫(kù)

雖然圖 18 GridView 中沒(méi)有顯示出來(lái), DetailsView 界面里缺少的產(chǎn)品字段 CategoryID SupplierID QuantityPerUnit 、等等 被賦上一個(gè)數(shù)據(jù)庫(kù) NULL 值。你可以通過(guò)履行下面一個(gè)步驟來(lái)看到這一點(diǎn):

1. Visual Studio 的服務(wù)器資源管理器

2. 展開(kāi) NORTHWND.MDF 數(shù)據(jù)庫(kù)節(jié)點(diǎn)

3. Products 數(shù)據(jù)表節(jié)電上右鍵點(diǎn)擊

4. 選擇“顯示表數(shù)據(jù)”

這將列出 Products 表中的所有記錄。如圖 19 所示,除了 ProductID ProductName UnitPrice 字段,我們的新產(chǎn)品的其它字段都為 NULL 值。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
19: 未在 DetailsView 中提供的產(chǎn)品的其它字段被賦予 NULL

我們可能希望給予一個(gè)或幾個(gè)這些字段的值一個(gè)默認(rèn)值,而不是 NULL ,要么是因?yàn)? NULL 并非最佳的默認(rèn)項(xiàng),要么是因?yàn)閿?shù)據(jù)庫(kù)字段本身不允許 NULL 值。為了實(shí)現(xiàn)這一點(diǎn),我們可以編程設(shè)置這些 DetailsView InputParameters 集合里的參數(shù)值。這項(xiàng)工作可以在 DetailsView ItemInserting 事件處理程序中完成,或者在 ObjectDataSource Inserting 事件處理程序。因?yàn)槲覀円呀?jīng)看過(guò)了如何在數(shù)據(jù) Web 服務(wù)器控件中如何使用 pre- post-level 的事件,這次讓我們探究一下 ObjectDataSource 的事件。

第四步 : CategoryID SupplierID 參數(shù)賦值

在這里我們假設(shè)當(dāng)我們的應(yīng)用程序通過(guò)這個(gè)界面添加一個(gè)新產(chǎn)品時(shí)應(yīng)該給 CategoryID SupplierID 字段賦值為 1 。如之前提及的, ObjectDataSource 控件有一對(duì) pre- post-level 的事件發(fā)生在數(shù)據(jù)更改過(guò)程中。當(dāng)它的 Insert() 方法被調(diào)用時(shí), ObjectDataSource 首先觸發(fā)它的 Inserting 事件,然后調(diào)用它的 Insert() 方法所映射到的業(yè)務(wù)方法,最后觸發(fā) Inserted 事件。這個(gè) Inserting 事件處理程序提供給我們一個(gè)處理輸入?yún)?shù)或者徹底取消此操作的最后機(jī)會(huì)。

注意 : 在一個(gè)真實(shí)的應(yīng)用程序中你很可能希望既讓用戶指定 category supplier 的值,又希望基于一定的標(biāo)準(zhǔn)和業(yè)務(wù)邏輯的基礎(chǔ)上選擇這個(gè)值(而不是盲目地選擇 ID 1 )。不管如何,這個(gè)例子闡明了如何在 ObjectDataSource pre-level 的事件中編程設(shè)置一個(gè)輸入?yún)?shù)的值。

花些時(shí)間為 ObjectDataSource Inserting 事件創(chuàng)建一個(gè)事件處理程序。注意到該事件處理程序的第二個(gè)輸入?yún)?shù)是一個(gè) ObjectDataSourceMethodEventArgs 類型的對(duì)象,它有一個(gè)屬性來(lái)存取參數(shù)集合( InputParameters ),還有一個(gè)屬性用來(lái)取消此操作( Cancel )。

protected void ObjectDataSource1_Inserting(object sender, ObjectDataSourceMethodEventArgs e)

{

}

此時(shí), InputParameters 屬性包含了通過(guò) DetailsView 賦值到 ObjectDataSource InsertParameters 集合。為了修改這些參數(shù)里的一個(gè)值,簡(jiǎn)單地使用: e.InputParameters[" paramName "] = value 。所以,為了設(shè)置 CategoryID SupplierID 1 ,把 Inserting 事件處理程序調(diào)整為如下:

protected void ObjectDataSource1_Inserting(object sender, ObjectDataSourceMethodEventArgs e)

{

e.InputParameters["CategoryID"] = 1;

e.InputParameters["SupplierID"] = 1;

}

這次當(dāng)我們添加一個(gè)新產(chǎn)品(例如 Acme Soda ),這個(gè)新產(chǎn)品的 CategoryID SupplierID 字段被賦值為 1 (見(jiàn)圖 20 )。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件
20: 現(xiàn)在,新產(chǎn)品的 CategoryID SupplierID 字段被設(shè)置為 1

總結(jié)

在編輯、插入和刪除的過(guò)程中,無(wú)論數(shù)據(jù) Web 服務(wù)器控件還是 ObjectDataSource 都會(huì)發(fā)生許多 pre- post-level 的事件。在這一節(jié)里,我們研究了 pre-level 的事件,并看到了如何在數(shù)據(jù) Web 服務(wù)器控件和 ObjectDataSource 的事件里使用它們來(lái)自定義輸入?yún)?shù)或取消當(dāng)前的數(shù)據(jù)更改操作。下一節(jié),我們將看看創(chuàng)建和使用 post-level 的事件的事件處理程序。

祝編程快樂(lè)!

作者簡(jiǎn)介

Scott Mitchell ,著有六本 ASP/ASP.NET 方面的書(shū),是 4GuysFromRolla.com 的創(chuàng)始人,自 1998 年以來(lái)一直應(yīng)用微軟 Web 技術(shù)。 Scott 是個(gè)獨(dú)立的技 術(shù)咨詢顧問(wèn),培訓(xùn)師,作家,最近完成了將由 Sams 出版社出版的新作, 24 小時(shí)內(nèi)精通 ASP.NET 2.0 。他的聯(lián)系電郵為 mitchell@4guysfromrolla.com ,也可以通過(guò)他的博客 http://ScottOnWriting.NET 與他聯(lián)系。

Scott Mitchell 的ASP.NET 2.0數(shù)據(jù)教程之十七:: 研究插入、更新和刪除的關(guān)聯(lián)事件


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 精品一区二区三区中文 | 国产精品国产三级国产专区5o | 欧美日韩亚洲国产精品 | 波多野结衣中文字幕一区二区 | 四虎永久免费地址 | 91免费网站在线看入口黄 | 日本一区二区三区四区公司 | 日韩欧美伦理 | 四虎播播 | 欧美精品专区第1页 | 国产成人精品午夜在线播放 | 免费在线a| 亚洲精品动漫一区二区三区在线 | 尤物精品视频在线观看 | 国产日韩欧美中文字幕 | 91视频地址| 九九re| 日韩久久精品视频 | 在线免费黄色片 | 五月婷婷丁香在线视频 | 奇米影视狠狠久久中文 | 国产色视频 | 久久精品23 | 亚洲精品蜜桃久久久久久 | 久久亚洲精中文字幕冲田杏梨 | 国产欧美日韩一区二区三区视频 | 亚洲一区二区福利视频 | 日韩久久影院 | 日本不卡一| 在线精品国精品国产不卡 | 亚洲国产欧美在线观看 | 欧美成人伊人十综合色 | 911视频免费版 | 亚洲香蕉影院 | 亚洲高清在线观看看片 | 亚洲精品色综合久久久 | 国产视频观看 | 欧美日韩不卡中文字幕在线 | 全部费免一级毛片不收费 | 伊人伊色| 国产女人水多毛片18 |