共用方式為


宣告式參數 (C#)

作者:Scott Mitchell

下載 PDF

在本教學中,我們將說明如何使用設定為硬編碼值的參數來選擇要在 DetailsView 控制項中顯示的資料。

簡介

上一篇教學中, 我們研究如何使用綁定到呼叫 ProductsBLL 類別中 GetProducts() 方法的 ObjectDataSource 控制項的 GridView、DetailsView 和 FormView 控制項來顯示資料。 GetProducts() 方法傳回一個強類別型的 DataTable,其中填入了 Northwind 資料庫 Products 表中的所有記錄。 ProductsBLL 類別包含用於僅傳回產品子集 GetProductByProductID(productID)GetProductsByCategoryID(categoryID)GetProductsBySupplierID(supplierID) 的附加方法。 這三個方法需要一個輸入參數來指示如何篩選返回的產品資訊。

ObjectDataSource 可用來呼叫需要輸入參數的方法,但為此我們必須指定這些參數的值來自何處。 參數值可以是硬編碼的,也可以來自各種動態來源,包括:查詢字串值、會話變數、頁面上 Web 控制項的屬性值或其他。

在本教學課程中,我們首先說明如何使用設定為硬編碼值的參數。 具體來說,我們將考慮在頁面上添加一個 DetailsView,用於顯示特定產品的信息,即 Chef Anton's Gumbo Mix,其值為 ProductID/5。 接下來,我們將了解如何基於Web控制項設定參數值。 特別是,我們將使用文字方塊讓使用者輸入一個國家/地區,然後他們可以點擊按鈕來查看位於該國家/地區的供應商清單。

使用硬編碼參數值

對於第一個範例,首先將 DetailsView 控制項新增至 BasicReporting 資料夾中的 DeclarativeParams.aspx 頁面。 從 DetailsView 的智慧標記中,從下拉清單中選擇<新資料來源>,然後選擇新增一個ObjectDataSource。

將 ObjectDataSource 新增至頁面

圖 1:將 ObjectDataSource 新增至頁面 (按一下查看全尺寸影像)

這將自動啟動 ObjectDataSource 控制項的選擇資料來源精靈。 從精靈的第一個畫面中選擇 ProductsBLL 類別。

選擇 ProductsBLL 類別

圖 2:選擇 ProductsBLL 類別 (點擊看大圖)

由於我們想要顯示有關特定產品的信息,因此我們想要使用 GetProductByProductID(productID) 方法。

選擇 GetProductByProductID(productID) 方法

圖3:選擇 GetProductByProductID(productID) 方法 (點擊看大圖)

由於我們選擇的方法包含一個參數,因此精靈也會出現一個螢幕,要求我們定義參數要使用的值。 左側清單顯示所選方法的所有參數。 因為GetProductByProductID(productID)只有一個productID。 在右側,我們可以指定所選參數的值。 參數來源下拉清單列舉了參數值的各種可能的來源。 由於我們要為 productID 參數指定硬編碼值 5,因此將參數來源保留為 None 並在 DefaultValue 文字方塊中輸入 5。

硬編碼參數值 5 將用於 ProductID 參數

圖 4:參數將使用硬編碼 productID 參數值 5 (點擊查看大圖)

完成「設定資料來源」精靈後,ObjectDataSource 控制項的聲明性標記在 SelectMethod 屬性中定義的方法所需的每個輸入參數的 SelectParameters 集合中包含一個 Parameter 物件。 由於我們在本例中使用的方法只需要一個輸入參數 parameterID,因此這裡只有一個條目。 SelectParameters 集合可以包含從 System.Web.UI.WebControls 命名空間中的 Parameter 類別派生的任何類別。 對於硬編碼參數值,使用 Parameter 基類別,但對於其他參數來源選項,使用衍生 Parameter 類別;如果需要,您也可以建立自己的 自訂參數類別型

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProductByProductID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:Parameter DefaultValue="5" Name="productID"
         Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

注意

如果您在自己的電腦上進行操作,此時您看到的聲明性標記可能包括 InsertMethodUpdateMethodDeleteMethod 屬性的值,以及 DeleteParameters。 ObjectDataSource 的選擇資料來源精靈會自動指定 ProductBLL 中用於插入、更新和刪除的方法,因此除非您明確清除這些方法,否則它們將包含在上面的標記中。

存取此頁面時,資料 Web 控制項會呼叫 ObjectDataSource 的方法,Select 方法將使用 productID 輸入參數的硬編碼值 5 來呼叫 ProductsBLL 類別的 GetProductByProductID(productID) 方法。 此方法將傳回一個強型別 ProductDataTable 物件,其中包含一行有關 Chef Anton 的 Gumbo Mix (具有 ProductID 5 的產品) 的資訊。

顯示 Chef Anton 濃湯混合的信息

圖 5:顯示有關 Chef Anton 濃湯混合的資訊 (點擊看大圖)

將參數值設定為 Web 控制項的屬性值

也可以根據頁面上 Web 控制項的值來設定 ObjectDataSource 的參數值。 為了說明這一點,我們有一個 GridView,它列出了位於使用者指定的國家/地區的所有供應商。 要完成此操作,請先為頁面新增一個文字框,使用者可以在其中輸入國家/地區名稱。 將此 TextBox 控制項的 ID 屬性設為 CountryName。 也新增一個按鈕 Web 控制項。

將文字方塊新增至 ID 為 CountryName 的頁面

圖 6:將文字方塊新增至頁面 IDCountryName (點擊查看全尺寸影像)

接下來,將 GridView 新增至頁面,並從智慧標記中選擇新增新的 ObjectDataSource。 由於我們想要顯示供應商訊息,因此從精靈的第一個畫面中選擇 SuppliersBLL 類別。 從第二個畫面中選擇 GetSuppliersByCountry(country) 方法。

選擇 GetSuppliersByCountry(country) 方法

圖 7:選擇 GetSuppliersByCountry(country) 方法 (點擊看大圖)

由於 GetSuppliersByCountry(country) 方法具有輸入參數,因此精靈再次包含用於選擇參數值的最終畫面。 這次,將參數來源設定為控制。 這將使用頁面上控制項的名稱填入 ControlID 下拉清單;從清單中選擇 CountryName 控制項。 第一次造訪該頁面時,CountryName 文字方塊將為空白,因此不會傳回任何結果,也不會顯示任何內容。 如果要預設顯示某些結果,請相應地設定 DefaultValue 文字方塊。

將參數值設定為 CountryName 控制值

圖 8:將參數值設定為CountryName控制值 (點選查看大圖)

ObjectDataSource 的宣告式標記與我們的第一個範例略有不同,它使用 ControlParameter 而不是標準 Parameter 物件。 ControlParameter 具有附加屬性來指定 Web 控制項的 ID 屬性以及用於參數 (PropertyName) 的屬性值。 設定資料來源精靈足夠智能,可以確定對於文字框,我們可能希望使用參數值的 Text 屬性。 但是,如果您想要使用與 Web 控制項不同的屬性值,您可以在此處變更 PropertyName 值,或按一下精靈中的「顯示進階屬性」連結。

<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
    SelectMethod="GetSuppliersByCountry" TypeName="SuppliersBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="CountryName"
          Name="country" PropertyName="Text"
            Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>

第一次造訪該頁面時,CountryName 文字方塊為空。 ObjectDataSource 的 Select 方法仍由 GridView 調用,但將 null 的值傳遞到 GetSuppliersByCountry(country) 方法中。 TableAdapter 將 null 轉換為資料庫 NULL 值 (DBNull.Value),但 GetSuppliersByCountry(country) 方法使用的查詢會編寫為在為 @CategoryID 參數指定 NULL 值時不傳回任何值。 簡而言之,沒有供應商被退回。

然而,一旦訪客進入某個國家/地區並點擊「顯示供應商」按鈕以引發回發,就會重新查詢 ObjectDataSource 的 Select 方法,並將 TextBox 控制項的 Text 值作為 country 參數傳遞。

顯示了來自加拿大的供應商

圖 9:顯示了來自加拿大的供應商 (點擊看大圖)

預設顯示所有供應商

我們可能希望首先顯示所有供應商,而不是在第一次查看頁面時不顯示任何供應商,從而允許使用者透過在文字方塊中輸入國家/地區名稱來縮減清單。 當 TextBox 為空時,SuppliersBLLGetSuppliersByCountry(country) 類別的方法將傳入其輸入 country 參數的 null 值。 然後,null 值被傳遞到 DAL 的 GetSupplierByCountry(country) 方法中,並在其中轉換為以下查詢中 @Country 參數的資料庫 NULL 值:

SELECT     SupplierID, CompanyName, Address, City, Country, Phone
FROM         Suppliers
WHERE Country = @Country

即使對於 Country 列有 NULL 值的記錄,表達式 Country = NULL 也始終傳回 False;因此,不會傳回任何記錄。

要在國家/地區文字方塊為空時傳回所有供應商,我們可以擴充 BLL 中的 GetSuppliersByCountry(country) 方法,以便在其國家/地區參數為 GetSuppliers()null 時呼叫 GetSuppliersByCountry(country) 方法,否則呼叫 DAL 的方法。 當未指定國家/地區時,這將傳回所有供應商;當包含國家/地區參數時,將傳回適當的供應商子集。

SuppliersBLL 類別中的 GetSuppliersByCountry(country) 方法變更為以下內容:

public Northwind.SuppliersDataTable GetSuppliersByCountry(string country)
{
    if (string.IsNullOrEmpty(country))
        return GetSuppliers();
    else
        return Adapter.GetSuppliersByCountry(country);
}

透過此更改,DeclarativeParams.aspx 頁面會在首次造訪時 (或 CountryName 文字方塊為空時) 顯示所有供應商。

現在預設顯示所有供應商

圖 10:現在預設顯示所有供應商 (點擊看大圖)

摘要

為了使用具有輸入參數的方法,我們需要指定 ObjectDataSource SelectParameters 集合中的參數值。 不同類別型的參數允許從不同的來源取得參數值。 預設參數類別型使用硬編碼值,但也可以輕鬆 (無需一行程式碼) 從查詢字串、會話變數、cookie 甚至頁面上的 Web 控制項中使用者輸入的值取得參數值。

我們在本教學中查看的範例說明如何使用聲明性參數值。 然而,有時我們可能需要使用不可用的參數來源,例如當前日期和時間,或者,如果我們的網站使用會員資格,則需要訪客的使用者 ID。 對於這種情況,我們可以在 ObjectDataSource 呼叫其底層物件的方法之前以程式設計方式設定參數值。 我們將在下一個教學課程中了解如何實現這一點。

快樂程式!

關於作者

Scott Mitchell 是七本 ASP/ASP.NET 書籍的作者和 4GuysFromRolla.com 的創始人,自 1998 年以來一直致力於 Microsoft Web 技術。 史考特是一名獨立顧問、培訓師和作家。 他的最新著作是 Sams Teach Yourself ASP.NET 2.0 in 24 Hours。 您可以撥打 mitchell@4GuysFromRolla.com 聯絡他。或者透過他的部落格, http://ScottOnWriting.NET部落格可以在以下位置找到。

特別感謝

本教學系列得到了許多有用的審閱者的審閱。 本教學的首席審閱者是 Hilton Giesenow。 有興趣查看我即將發表的 MSDN 文章嗎? 如果是這樣,請留言給我 mitchell@4GuysFromRolla.com