程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> ASP.NET基礎 >> 在ASP.NET 2.0中操作數據之十七:研究插入、更新和刪除的關聯事件

在ASP.NET 2.0中操作數據之十七:研究插入、更新和刪除的關聯事件

編輯:ASP.NET基礎

導言

  當使用GridView、DetailsView或FormView控件的內建插入、編輯或刪除特征時,在用戶添加一條新記錄或更新/刪除一條現在記錄的過程中發生了多個步驟。正如我們之前一節裡所討論的,在GridView中編輯一行時,保存(Update)和取消(Cancel)按鈕將取代編輯(Edit)按鈕,並且綁定列轉換成TextBox。在用戶更新了數據並點擊保存按鈕之後,下述步驟在回傳時執行:

1.該GridView控件根據當前編輯行的唯一標識字段(通過DataKeyNames屬性)組裝它的ObjectDataSource的UpdateParameters參數,連同用戶輸入的值

2.該GridView控件調用它的ObjectDataSource的Update()方法,它轉而調用潛在對象的適當的方法(ProductsDAL.UpdateProduct,我們之前一節裡)

3.現在,這些隱含的數據,包含保存後的更改,被重新綁定到GridView控件

  在這一連串的步驟裡,觸發了許多事件,這讓我們可以創建事件處理程序從而在需要的地方增加自定義邏輯。例如,在第1步之前,觸發GridView的事件。在這裡,如果有什麼validation錯誤我們可以取消更新請求。當調用Update()方法時,觸發ObjectDataSource的Updating事件,提供了增加或自定義UpdateParameters的值的機會。在ObjectDataSource的潛在對象的方法完全執行後,觸發ObjectDataSource的Updated事件。針對Updated事件的事件處理程序可以檢查更新操作的相關詳細信息,例如影響了多少行數據,或者是否引發了一個異常。最後,在第2步之後,GridView的RowUpdated事件觸發;針對此事件的事件處理程序可以檢查關於剛剛完成的更新操作的相關額外信息。

  圖1描述了使用GridView更新時這一系列連續的事件和步驟。圖1裡的這個事件模式不僅是在GridView的更新操作。從GridView、DetailsView或者FormView裡插入、更新或者刪除數據時,數據Web服務器控件和ObjectDataSource都會發生這一連串的pre-level和post-level的事件。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521034.png

圖1: 當在GridView裡更新數據時,觸發一連串的Pre-和Post-事件

  在這一節裡,我們將探討使用這些事件從而擴展ASP.NET數據Web服務器控件的內建插入、更新和刪除功能。我們也會看看如何自定義編輯界面從而僅僅更新部分產品字段。

第一步: 更新產品的ProductName和UnitPrice字段

  在之前一節的編輯界面裡,包含了產品的所有字段並且它們都不是只讀的。如果我們從GridView中剔除一列(QuantityPerUnit),那麼當更新時數據Web服務器控件就不會設置ObjectDataSource的QuantityPerUnit UpdateParameters的值。ObjectDataSource則傳入一個null值到UpdateProduct這個業務邏輯層的方法,它將當前編輯的數據庫記錄的QuantityPerUnit字段更改為值。同樣地,如果是一個必需的字段,例如ProductName,如果從編輯界面中剔除了,那麼此更新將會失敗並拋出一個“Column 'ProductName' does not allow nulls”異常。導致這一現象的原因是ObjectDataSource被配置為調用ProductsBLL類的UpdateProduct方法,它預期每一個產品字段都對應一個輸入參數。因此,ObjectDataSource的UpdateParameters集合包含了該方法的每一個輸入參數。

  如果我們希望提供一個允許最終用戶僅僅可以更新部分字段的數據Web服務器控件,那麼我們需要在ObjectDataSource的Updating事件處理程序中編程設置缺失的UpdateParameters值,或者創建並調用一個預期部分字段的BLL方法。讓我們在接下來的步驟中探討。

  特別地,讓我們創建一個在一個可編輯的GridView中僅顯示ProductName和UnitPrice字段的頁面。這個GridView的編輯界面將僅僅允許用戶更新兩個顯示的字段,ProductName和UnitPrice 。因為這個編輯界面僅僅提供產品的部分字段,我們需要創建一個ObjectDataSource,它使用現有的BLL的UpdateProduct方法並在Updating事件處理程序中編程設置產品的缺少的字段的值,或者我們需要創建一個新的BLL方法,它僅接受那些在GridView中已經定義的部分字段。在這一節裡,我們使用後者,創建一個UpdateProduct方法的重載,它提取3個輸入參數: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方法類似,這個重載方法首先檢查是否在數據庫中存在一個指定ProductID的產品。如果不存在,它返回false,指示更新產品信息的請求失敗。否則,它因而更新現存的產品記錄的ProductName和UnitPrice字段並通過調用TableAdapter的Update()方法提交此更新,傳入ProductsRow實例。

  通過這些對我們的ProductsBLL類的額外處理,我們現在可以創建一個簡單GridView界面。打開EditInsertDelete文件夾中的DataModificationEvents.aspx ,添加一個GridView控件到頁面。新建一個ObjectDataSource並配置它使用ProductsBLL類,它的Select()方法映射到GetProducts ,Update()方法映射到僅接受productName、unitPrice和productID輸入參數的UpdateProduct方法重載。圖2展示了映射ObjectDataSource的Update()方法到ProductsBLL類的新的UpdateProduct方法重載時的數據源配置向導。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521192.png

圖 2: 映射ObjectDataSource的Update()方法到新的UpdateProduct重載

  因為我們的例子將僅僅需要編輯數據的能力,不需要插入或刪除記錄,那麼花些時間明確地指明該ObjectDataSource的Insert()和Delete()方法不會映射到ProductsBLL類的任何方法--通過到INSERT和DELETE的tab頁並從下拉列表中選擇(無)。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521155.png

圖 3: 在INSERT和DELETE的Tab頁,從下拉列表中選擇(無)

完成了此向導後,從GridView的職能標記裡勾選上啟用編輯。

完成了此數據源配置向導並綁定到GridView後,Visual Staudio就已經添加好它們的聲明語法。到源視圖察看該ObjectDataSource的聲明標記,它將如下所示:

[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;
}

  因為ObjectDataSource的Insert()和Delete()方法沒有映射,也就沒有InsertParameters或者DeleteParameters片段。此外,因為方法映射到UpdateProduct方法重載,它僅接受3個輸入參數,UpdateParameters片段也就僅包含3個Parameter實例。

  注意到ObjectDataSource的屬性被設置為original_{0}。這個屬性是使用數據源配置向導時Visual Studio自動設置的。因此,由於我們的BLL方法不需要傳入原始的ProductID值,從ObjectDataSource的聲明語法中刪除所有這些屬性設置。

  注意: If you如果你只是簡單地在設計視圖裡從屬性窗口清除OldValuesParameterFormatString屬性的值,這個屬性會依舊存在於聲明語法裡,但會被設置為一個空字符串。要麼從聲明語法裡把該屬性通通刪掉,要麼從屬性窗口,設置它的值為默認值:{0} 。

雖然ObjectDataSource僅僅包含對productName、unitPrice和productID的UpdateParameters,Visual Studio還是為產品的每一個字段添加一個綁定列或CheckBoxField。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521114.png

圖 4: 對應產品的每一個字段,GridView都包含一個BoundField或CheckBoxField

  當最終用戶編輯一個產品並點擊它的保存按鈕(Update),該GridView遍歷那些可編輯的字段,然後把用戶輸入的值賦值到ObjectDataSource的UpdateParameters集合裡對應的參數。如果沒有對應的參數,GridView則添加一個到參數集合裡。因此,如果我們的GridView包含對應產品的所有字段的綁定列或CheckBox列,那麼ObjectDataSource則會調用能接受這些參數的方法重載,而不顧ObjectDataSource的聲明標記指定只接受3個輸入參數的事實(見圖5)。類似地,如果存在某些由GridView非只讀列構成的組合,而沒有一個UpdateProduct重載能接受相應的參數,則會在試圖保存時引發一個異常。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521146.png

圖 5: GridView將添加參數到ObjectDataSource的UpdateParameters集合

  為了確保ObjectDataSource調用僅接受productName、unitPrice和productID參數的UpdateProduct重載,我們需要限定GridView僅包含ProductName和UnitPrice這兩個可編輯的列。這可以通過刪除其他綁定列和CheckBox列,或者把這些列的ReadOnly屬性設置為true實現,又或者上述兩種方法結合使用。在本節裡讓我們簡單地刪除除了ProductName和UnitPrice綁定列以外的GridView的所有列,然後,GridView的聲明標記將如下所示:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
  DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
  <Columns>
    <asp:CommandField ShowEditButton="True" />
    <asp:BoundField DataField="ProductName"
     HeaderText="ProductName" SortExpression="ProductName" />
    <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
     SortExpression="UnitPrice" />
  </Columns>
</asp:GridView>

  即使重載預期3個輸入參數,在我們的GridView裡僅包含兩個綁定列。這是因為productID輸入參數是一個主鍵(primary key)的值,它通過當前編輯行的DataKeyNames屬性傳入值。

  我們的GridView控件,連同這個UpdateProduct重載,允許一個用戶僅僅編輯產品的名稱和單價而不會丟失產品的其他字段。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521269.png

圖 6: 僅允許編輯 ProductName和UnitPrice的界面

完善UnitPrice格式化

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

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521273.png

圖 7: 設置UnitPrice綁定列的DataFormatString和HtmlEncode屬性

通過此項更改,處於非編輯狀態的行將價格格式化為貨幣;然而,當前編輯的行,仍然顯示為沒有貨幣符號並保留四位小數。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521215.png

圖 8: 現在,非編輯狀態的行格式化為貨幣值

通過設置此綁定列的ApplyFormatInEditMode屬性為true(默認為false),可以把DataFormatString屬性裡指定的格式化指令應用到編輯界面。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521220.png

圖 9: 設置此綁定列的ApplyFormatInEditMode屬性為true

通過這個更改,當前編輯行裡顯示的UnitPrice值也被格式化為貨幣。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521338.png

圖 10: 現在,當前編輯行的值也被格式化為貨幣

  然而,如果把產品價格更新為文本框裡帶貨幣符號的值– 例如$19.00 – 則會拋出一個FormatException異常。當GridView嘗試把用戶提供的值賦值到ObjectDataSource的UpdateParameters集合,它無法把UnitPrice字符串“$19.00”轉換成參數要求的decimal類型(見圖11)。為了補救這個問題我們可以為GridView的RowUpdating事件添加一個事件處理程序並讓它把用戶輸入的UnitPrice格式化為貨幣格式的decimal 。

  這個GridView的RowUpdating事件接受的第二個參數是一個GridViewUpdateEventArgs類型的對象,它包含一個NewValues字典,當中的每一個屬性保存著用戶輸入的值,准備賦值到ObjectDataSource的UpdateParameters集合。我們可以重寫現有的NewValues集合中的UnitPrice值為一個貨幣金額,通過下面的事件處理程序中的代碼進行解析:

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);
}

  如果用戶提供了一個諸如“$19.00”的UnitPrice值,這個值會被通過Decimal.Parse計算並解析為貨幣金額的值重寫。這將正確的解析貨幣值,無論是貨幣符號、逗號、小數點、等等,並使用System.Globalization命名空間的NumberStyles枚舉。

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

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521327.png

圖 11: 現在,當前編輯行的UnitPrice值被格式化為貨幣金額

第二步: 阻止NULL UnitPrices

  雖然數據庫被配置為允許Products表裡的UnitPrice字段為NULL值,但我們可能希望防止用戶訪問這個特別的頁面並指定一個空的UnitPrice值。更確切地說,如果用戶在編輯一個產品行記錄時忘記輸入一個UnitPrice值, 與其保存這個結果到數據庫,我們還不如給用戶顯示一個提示信息,自始至終這個頁面,任何的對產品的編輯必須指定一個價格。

  傳入到GridView的事件處理程序的GridViewUpdateEventArgs對象包含一個Cancel屬性,如果把它設置為true,則中止這個更新過程。讓我們擴展RowUpdating事件處理程序,設置e.Cancel為true並顯示一個信息說明為什麼在NewValues集合裡的UnitPrice值為null 。

  首先,添加一個Label服務器控件到頁面並命名為MustProvideUnitPriceMessage 。這個Label控件將顯示用戶是否在更新一個產品時忘記指定一個UnitPrice值。設置這個Label的Text屬性為“您必須為產品提供一個價格。”。我也已經在Styles.css文件中添加了一個名為Warning的新CSS類別,定義如下:

.Warning
{
  color: Red;
  font-style: italic;
  font-weight: bold;
  font-size: x-large;
}

最後,設置Label的CssClass屬性為Warning 。這樣設計器中將在GridView上方顯示這個紅色、斜體、加粗、並且較大字體的警告信息。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521368.png

圖 12: 一個Label控件已被添加到GridView上方

默認地,這個Label控件隱藏,那麼在Page_Load事件處理程序中設置它的Visible屬性為false 。

protected void Page_Load(object sender, EventArgs e)
{
  MustProvideUnitPriceMessage.Visible = false;
}

如果用戶嘗試更新一個產品並不指定UnitPrice值,我們希望取消這個更新並顯示警告標簽。在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;
  }
}

如果一個用戶試圖保存一個產品並不指定價格,這個更新操作就被取消並顯示一個有用的提示信息。雖然數據庫(和業務邏輯)允許NULL值的UnitPrice,但這個特定的ASP.NET頁面不允許。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521393.png

圖 13: 用戶不能讓UnitPrice為空

  到目前為止我們看過了如何使用GridView的RowUpdating事件來編程改變賦值到ObjectDataSource的UpdateParameters集合的參數值,還有如何完全地取消這個更新過程。這些思想也可以延展至DetailsView和FormView控件並且應用到插入或刪除。

  這些任務也可以在ObjectDataSource這一層通過的Inserting、Updating和Deleting事件處理程序完成。這些事件在隱含對象的關聯方法被調用前觸發,並且提供一個更改輸入參數集合或者完全取消此操作的最後機會。對應這3個事件的事件處理程序傳入一個ObjectDataSourceMethodEventArgs 類型的對象,我們對它的這兩個屬性感興趣:

·Cancel,它如果被設置為true,取消執行中的操作

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

  為了舉例說明在ObjectDataSource這一層如何處理參數的值,讓我們在頁面裡包含一個DeailsView,它允許用戶新增一個新的產品記錄。這個DetailsView將用作提供一個快捷的方式添加一個新的產品記錄到數據庫。為了在新增產品時保持界面一致,我們僅允許用戶輸入ProductName和UnitPrice字段。作為默認值,這些在DetailsView的插入界面提供的值將被設置為一個數據庫的NULL值。不過,我們可以使用ObjectDataSource的Inserting事件注入不同的默認值,正如我們馬上要看的。

第三步: 提供一個添加新產品的界面

  在GridView的上方,從工具箱裡拖放一個DetailsView控件到設計器,清空它的Height和Width屬性,並將它綁定到頁面中已經存在的ObjectDataSource 。這將為產品的每一個字段添加一個綁定列或CheckBox列。因為我們希望用這個DetailsView控件來添加新產品,我們需要從它的職能標記裡勾選啟用插入這一項;然而並沒有這一項,這是因為此ObjectDataSource的Insert()方法還沒有映射到ProductsBLL類的方法(回想起我們在配置數據源時設置了這個映射為(無) – 見圖3)。

  為了再次配置這個ObjectDataSource,從它的職能標記中選擇“配置數據源”的鏈接,載入向導。第一屏允許你更改ObjectDataSource綁定到的隱含對象;讓它依舊是ProductsBLL 。下一屏列出從ObjectDataSource到隱含對象的方法的映射。盡管我們已經明確地指定Insert()和Delete()不映射到任何方法,然而如果你到INSERT和DELETE的tab頁你還是會看到那裡有一個映射。這是因為ProductsBLL的AddProduct和DeleteProduct方法使用了DataObjectMethodAttribute指出它們分別是為Insert()和Delete()服務的默認的方法。因此,ObjectDataSource向導在每次運行時都會自動地選擇它們,除非那裡被明確地指定了一個別的值。

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

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521433.png

圖 14: 從INSERT的Tab頁的下拉列表中選擇AddProduct方法

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521434.png

圖 15: 從DELETE的Tab頁的下拉列表中選擇(無)

完成了這些更改後,該ObjectDataSource的聲明語法中將包含一個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>

  再次運行向導導致重新添加OldValuesParameterFormatString屬性。把這個屬性設置為默認值({0})或者從聲明語法中把它們完全刪除。

  隨著ObjectDataSource提供插入數據的能力,現在DetailsView的職能標記裡包含“啟用插入”的checkbox;回到設計器並勾選這一項。然後,減少DetailsView的列直道它只包含兩個綁定列- ProductName和UnitPrice ,還有一個CommandField。此時DetailsView的聲明語法將如下所示:

<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
  DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
  <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展現的是在此時通過浏覽器查看的頁面。正如你所看到的,DetailsView列出第一個產品(Chai)的名稱和價格。不過,我們需要的是一個插入界面來提供一個用戶快速增加一個新產品到數據庫的手段。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521477.png

圖16: 該DetailsView當前呈現在只讀模式

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

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521420.png

圖 17: 這個DetailsView提供了一個快速添加新產品的界面

  當用戶輸入一個產品名稱和價格(例如“Acme Wate”和1.99,如圖17)並點擊插入按鈕,發生回傳並且開始插入的工作流程,直到最後添加一個新產品記錄到數據庫。DetailsView維持在它的插入界面,並且GridView自動地重現綁定到它的數據源,目的是為了包含新增加的產品,如圖18所示。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521592.png

圖 18: 產品“Acme Water”已經被添加到數據庫

  雖然圖18的GridView中沒有顯示出來,DetailsView界面裡缺少的產品字段 – CategoryID、SupplierID、QuantityPerUnit、等等 – 被賦上一個數據庫NULL值。你可以通過履行下面一個步驟來看到這一點:

1.到Visual Studio的服務器資源管理器

2.展開NORTHWND.MDF數據庫節點

3.在Products數據表節電上右鍵點擊

4.選擇“顯示表數據”

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

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521531.png

圖 19: 未在DetailsView中提供的產品的其它字段被賦予NULL值

  我們可能希望給予一個或幾個這些字段的值一個默認值,而不是NULL,要麼是因為NULL並非最佳的默認項,要麼是因為數據庫字段本身不允許NULL值。為了實現這一點,我們可以編程設置這些DetailsView的InputParameters集合裡的參數值。這項工作可以在DetailsView的ItemInserting事件處理程序中完成,或者在ObjectDataSource的Inserting事件處理程序。因為我們已經看過了如何在數據Web服務器控件中如何使用pre-和post-level的事件,這次讓我們探究一下ObjectDataSource的事件。

 第四步: 給CategoryID和SupplierID參數賦值

  在這裡我們假設當我們的應用程序通過這個界面添加一個新產品時應該給CategoryID和SupplierID字段賦值為1。如之前提及的,ObjectDataSource控件有一對pre-和post-level的事件發生在數據更改過程中。當它的Insert()方法被調用時,ObjectDataSource首先觸發它的Inserting事件,然後調用它的Insert()方法所映射到的業務方法,最後觸發Inserted事件。這個Inserting事件處理程序提供給我們一個處理輸入參數或者徹底取消此操作的最後機會。

  注意: 在一個真實的應用程序中你很可能希望既讓用戶指定category和supplier的值,又希望基於一定的標准和業務邏輯的基礎上選擇這個值(而不是盲目地選擇ID為1)。不管如何,這個例子闡明了如何在ObjectDataSource的pre-level的事件中編程設置一個輸入參數的值。

  花些時間為ObjectDataSource的Inserting事件創建一個事件處理程序。注意到該事件處理程序的第二個輸入參數是一個ObjectDataSourceMethodEventArgs類型的對象,它有一個屬性來存取參數集合(InputParameters),還有一個屬性用來取消此操作(Cancel)。

protected void ObjectDataSource1_Inserting
  (object sender, ObjectDataSourceMethodEventArgs e)
{

}

  此時,InputParameters屬性包含了通過DetailsView賦值到ObjectDataSource的InsertParameters集合。為了修改這些參數裡的一個值,簡單地使用:e.InputParameters["paramName"] = value 。所以,為了設置CategoryID和SupplierID為1,把Inserting事件處理程序調整為如下:

protected void ObjectDataSource1_Inserting
  (object sender, ObjectDataSourceMethodEventArgs e)
{
  e.InputParameters["CategoryID"] = 1;
  e.InputParameters["SupplierID"] = 1;
}

這次當我們添加一個新產品(例如Acme Soda),這個新產品的CategoryID和SupplierID字段被賦值為1(見圖20)。

https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017010916521536.png

圖 20: 現在,新產品的CategoryID和SupplierID字段被設置為1

總結

  在編輯、插入和刪除的過程中,無論數據Web服務器控件還是ObjectDataSource都會發生許多pre-和post-level的事件。在這一節裡,我們研究了pre-level的事件,並看到了如何在數據Web服務器控件和ObjectDataSource的事件裡使用它們來自定義輸入參數或取消當前的數據更改操作。下一節,我們將看看創建和使用post-level的事件的事件處理程序。

祝編程快樂!

作者簡介

Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用微軟Web技術。Scott是個獨立的技 術咨詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯系電郵為[email protected],也可以通過他的博客http://ScottOnWriting.NET與他聯系。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved