使用 ObjectDataSource 顯示資料 (C#)

by Scott Mitchell

下載 PDF

本教學介紹 ObjectDataSource 控件 使用此控件,您可以綁定從上一教學中建立的 BLL 擷取的資料,而無需編寫一行程式碼!

簡介

應用程式架構和網站頁面佈局完成後,我們準備開始探索如何完成各種常見的資料和報告相關任務。 在前面的教學中,我們了解如何以程式設計方式將資料從 DAL 和 BLL 綁定到 ASP.NET 頁面中的資料 Web 控制項。 這種將資料 Web 控制項的 DataSource 屬性指派給要顯示的資料,然後呼叫控制項的方法的語法是 ASP.NET 1.x 應用程式中使用的模式,並且可以繼續在 2.0 應用程式中使用 DataBind()。 然而,ASP.NET 2.0 的新資料來源控制項提供了一種處理資料的聲明性方式。 使用這些控制項,可以將上一個教學課程中建立的 BLL 所擷取的資料綁定,而且不需要撰寫任何程式碼!

ASP.NET 2.0 隨附了五個內建資料來源控制項:SqlDataSource、AccessDataSource、ObjectDataSource、XmlDataSource 和 SiteMapDataSource,如果您有需要,還可以建立自己的自訂資料來源控制項。 由於我們已經為教學課程應用程式開發了一個體系結構,因此我們將針對 BLL 類別使用 ObjectDataSource。

ASP.NET 2.0 包括五個內建資料來源控制項

圖 1:ASP.NET 2.0 包含五個內建資料來源控制項

ObjectDataSource 充當處理其他物件的代理程式。 為了設定 ObjectDataSource,我們指定此底層物件以及其方法如何對應到 ObjectDataSource 的 Select、Insert、Update 和 Delete 方法。 一旦指定了該底層物件並將其方法對應到 ObjectDataSource 的方法,我們就可以將 ObjectDataSource 綁定到資料 Web 控制項。 ASP.NET 附帶了許多資料 Web 控制項,包括 GridView、DetailsView、RadioButtonList 和 DropDownList 等。 在頁面生命週期中,資料 Web 控制項可能需要存取其綁定的資料,這將透過呼叫其 ObjectDataSource 的 Select 方法來完成;如果資料 Web 控制項支援插入、更新或刪除,則可以呼叫其 ObjectDataSource 的 InsertUpdateDelete 方法。 然後,這些呼叫由 ObjectDataSource 路由到適當的底層物件的方法,如下圖所示。

ObjectDataSource 擔任代理角色

圖 2:ObjectDataSource 充當代理程式 (按一下查看大圖)

雖然 ObjectDataSource 可用於呼叫插入、更新或刪除資料的方法,但我們只專注於返回資料;未來的教學將探討如何使用 ObjectDataSource 和修改資料的資料 Web 控制項。

步驟 1: 新增和設定 ObjectDataSource 控件

首先開啟 SimpleDisplay.aspx 資料夾中的 BasicReporting 頁面,切換到設計檢視,然後將 ObjectDataSource 控制項從工具箱拖曳到頁面的設計表面上。 ObjectDataSource 在設計圖面上顯示為灰色框,因為它不會產生任何標記;它只是透過呼叫指定物件的方法來存取資料。 ObjectDataSource 傳回的資料可以透過資料 Web 控制項(例如 GridView、DetailsView、FormView 等)顯示。

注意

或者,您可以先將資料 Web 控制項新增至頁面,然後從其智慧標記的下拉清單中選擇<新資料來源>選項。

若要指定 ObjectDataSource 的基礎物件以及該物件的方法如何對應到 ObjectDataSource 的方法,請按一下 ObjectDataSource 智慧標記中的「設定資料來源」連結。

按一下智慧標籤中的設定資料來源連結

圖 3:按一下 Smart Tag 中的設定資料來源連結 (按一下以查看完整尺寸圖像)

這將開啟設定資料來源精靈。 首先,我們必須指定 ObjectDataSource 要使用的物件。 如果選取「僅顯示資料組件」複選框,則此畫面上的下拉清單將只列出那些已用DataObject屬性修飾的物件。 目前,我們的清單包括類別型化資料集中的 TableAdapter 以及我們在上一教學中建立的 BLL 類別。 如果您忘記將 DataObject 屬性添加至業務邏輯層類別,您將不會在此清單中看到它們。 在這種情況下,取消勾選「僅顯示資料元件」複選框以查看所有物件,其中應包括 BLL 類別 (以及類別型化資料集中的其他類別,例如 DataTable、DataRow 等)。

在第一個畫面中,從下拉清單中選擇ProductsBLL類別,然後按一下「下一步」。

指定要與 ObjectDataSource 控制項一起使用的物件

圖 4:指定要與 ObjectDataSource 控制項一起使用的物件 (按一下檢視全尺寸影像)

精靈中的下一個畫面將提示您選擇 ObjectDataSource 應呼叫的方法。 下拉清單列出了傳回從上一畫面選取的物件中的資料的方法。 在這裡我們看到 GetProductByProductIDGetProductsGetProductsByCategoryIDGetProductsBySupplierID。 從下拉清單中選擇 GetProducts 方法,然後按一下「完成」(如果您在上一個教學中將 DataObjectMethodAttribute 加入 ProductBLL 的方法,則此選項將預設被選取)。

從 SELECT 索引標籤中選擇資料傳回的方法

圖 5:選擇從 SELECT 標籤傳回資料的方法(按一下查看全尺寸影像)

手動配置 ObjectDataSource

ObjectDataSource 的設定資料來源精靈提供了一種快速方法來指定它使用的物件並關聯調用該物件的哪些方法。 但是,您可以透過「屬性」視窗或直接在聲明性標記中透過其屬性來設定 ObjectDataSource。 只需將 TypeName 屬性設定為要使用的基礎物件的類型,以及擷取資料時呼叫的 SelectMethod 方法即可。

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
    SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>

即使您喜歡「設定資料來源」精靈,有時也可能需要手動設定 ObjectDataSource,因為該精靈僅列出開發人員建立的類別。 如果要將 ObjectDataSource 綁定到 .NET Framework 中的類別,例如 Membership 類別 來存取使用者帳戶訊息,或將 Directory 類別 用於處理檔案系統訊息,則需要手動設定 ObjectDataSource 的屬性。

步驟 2:新增資料 Web 控制項並將其綁定到 ObjectDataSource

將 ObjectDataSource 新增至頁面並進行設定後,我們就可以將資料 Web 控制項新增至頁面,以顯示 ObjectDataSource 的 Select 方法所傳回的資料。 任何資料 Web 控制項都可以綁定到 ObjectDataSource;讓我們來看看如何在 GridView、DetailsView 和 FormView 中顯示 ObjectDataSource 的資料。

將 GridView 綁定到 ObjectDataSource

將 GridView 控制項從工具箱新增至 SimpleDisplay.aspx 的設計介面。 從 GridView 的智慧標記中,選擇我們在步驟 1 中新增的 ObjectDataSource 控制項。 這將自動在 GridView 中為 ObjectDataSource 的 Select 方法所傳回資料的每個屬性(即由 Products DataTable 所定義的屬性)建立一個 BoundField。

GridView 已新增至頁面並綁定至 ObjectDataSource

圖 6:已將 GridView 新增至頁面,並綁定至 ObjectDataSource (點擊檢視全尺寸影像)

然後,您可以透過點擊智慧標記中的「編輯列」選項來自訂、重新排列或刪除 GridView 的 BoundFields。

透過編輯欄位對話框管理 GridView 的 BoundFields

圖 7:透過「編輯欄位」對話方塊管理 GridView 的 BoundFields (點擊以查看完整圖片)

花點時間修改 GridView 的 BoundFields,刪除 ProductIDSupplierIDCategoryIDQuantityPerUnitUnitsInStockUnitsOnOrderReorderLevel BoundFields。 只需從左下角的清單中選擇 BoundField 並點擊刪除按鈕 (紅色 X) 即可將其刪除。 接下來,選擇這些 BoundField 並點擊向上箭頭,重新排列 BoundField,讓 CategoryNameSupplierName BoundField 位於 UnitPrice BoundField 之前。 將其餘 BoundFields 的 HeaderText 屬性分別設為 ProductsCategorySupplierPrice。 接下來,透過將Price BoundField 的HtmlEncode屬性設為 False 並將DataFormatString屬性設為{0:c},將 BoundField 格式化為貨幣。 最後,透過 ItemStyle/HorizontalAlign 屬性將 Price 水平對齊至右側,並將 Discontinued 複選框水平居中。

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName"
         HeaderText="Product" SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName"
          HeaderText="Category" ReadOnly="True"
          SortExpression="CategoryName" />
        <asp:BoundField DataField="SupplierName"
          HeaderText="Supplier" ReadOnly="True"
          SortExpression="SupplierName" />
        <asp:BoundField DataField="UnitPrice"
          DataFormatString="{0:c}" HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:CheckBoxField DataField="Discontinued"
          HeaderText="Discontinued" SortExpression="Discontinued">
            <ItemStyle HorizontalAlign="Center" />
        </asp:CheckBoxField>
    </Columns>
</asp:GridView>

GridView 的 BoundFields 已被自訂

圖 8:GridView 的 BoundFields 已自訂 (點擊查看大圖)

使用主題以獲得一致的外觀

這些教程力求刪除任何控制層級樣式設置,而是盡可能使用在外部文件中定義的「級聯樣式表」。 該 Styles.css 文件包含 DataWebControlStyleHeaderStyleRowStyleAlternatingRowStyle CSS 類別,這些類別應用於定義這些教學課程中使用的資料 Web 控制項的外觀。 為了實現這一點,我們可以將 GridView 的 CssClass 屬性設為 DataWebControlStyle,並相應設置其 HeaderStyleRowStyleAlternatingRowStyle 屬性的 CssClass 屬性。

如果我們在 Web 控制項上設定這些 CssClass 屬性,我們需要記住要明確地為新增到我們教學中的每一個資料 Web 控制項設定這些屬性值。 更容易管理的方法是使用主題為 GridView、DetailsView 和 FormView 控制項定義預設的 CSS 相關屬性。 主題是控制項級屬性設定、影像和 CSS 類別的集合,可套用於網站上的頁面以強制執行通用的外觀和感覺。

我們的佈景主題不會包含任何影像或 CSS 檔案(我們將保留樣式表 Styles.css 不變,定義於 Web 應用程式的根資料夾中),但將包含兩個樣式表。 外觀是定義 Web 控制項預設屬性的檔案。 具體來說,我們將為 GridView 和 DetailsView 控制項提供一個樣式檔,用於指示預設CssClass相關屬性。

首先,將新的外觀檔案新增至您的專案中,方法是右鍵點擊方案總管中的專案名稱,然後選擇「新增項目」,並將其命名為GridView.skin

新增名為 GridView.skin 的外觀文件

圖 9:新增名為 GridView.skin 的造型檔案 (按一下查看完整圖片)

造型文件需要放在App_Themes資料夾中的一個主題中。 由於我們還沒有這樣的資料夾,Visual Studio 會在新增第一個外觀時為我們建立一個資料夾。 點擊是以建立 App_Theme 資料夾並將新 GridView.skin 檔案放置在其中。

讓 Visual Studio 建立 App_Theme 資料夾

圖 10:讓 Visual Studio 建立 資料夾 (按一下查看大圖)

這將在App_Themes資料夾中建立一個名為 GridView 且包含 GridView.skin 的 Skin 檔案的新主題。

GridView 主題已新增至 App_Theme 資料夾

圖 11:GridView 主題已新增至資料夾中

將 GridView 主題重新命名為 DataWebControls(在 App_Theme 資料夾中的 GridView 資料夾上點擊右鍵,然後選擇「重新命名」)。 接下來,將以下標記輸入到 GridView.skin 文件中:

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
</asp:GridView>

這定義了使用 DataWebControls 佈景主題的任何頁面中任何 GridView 相關屬性的預設屬性。 讓我們為 DetailsView 添加另一個樣式,這是我們將會使用的資料 Web 控制項。 新增一個新造型至 DataWebControls 主題,命名為 DetailsView.skin 並新增以下程式碼:

<asp:DetailsView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <FieldHeaderStyle CssClass="HeaderStyle" />
</asp:DetailsView>

定義了主題後,最後一步是將主題套用到我們的 ASP.NET 頁面。 主題可以逐頁應用,也可以應用於網站中的所有頁面。 讓我們在網站的所有頁面上使用這個主題。 若要實現此目的,請將以下標記新增至 Web.config<system.web> 部分:

<pages styleSheetTheme="DataWebControls" />

這就是全部了! 該 styleSheetTheme 設定指示主題中指定的屬性應 覆寫在控制層設定的屬性。 若要指定主題設定應優先於控制設定,請使用 theme 屬性代替 styleSheetTheme;不幸的是,透過 theme 屬性指定的主題設定不會出現在 Visual Studio 設計檢視中。 有關主題和造型的更多詳細資訊,請參考ASP.NET 主題和造型概述使用主題的伺服器端樣式;設定頁面以使用主題的方式,請參閱如何應用 ASP.NET 主題

GridView 顯示產品的名稱、類別、供應商、價格和停產資訊。

圖 12:GridView 顯示產品名稱、類別、供應商、價格和停產資訊 (點擊查看完整尺寸圖片)

在詳細資料檢視中一次顯示一筆記錄

GridView 為它所綁定的資料來源控制項所傳回的每筆記錄顯示一行。 然而,有時我們可能希望一次顯示一筆記錄或僅顯示一筆記錄。 DetailsView 控制項提供了此功能,並呈現為 HTML 表格,其中綁定到該控制項的每個屬性在表格中作為一行,具有兩個欄位。 您可以將 DetailsView 視為帶有旋轉 90 度的單一記錄的GridView。

首先在 SimpleDisplay.aspx 中的 GridView 上方 新增一個 DetailsView 控制項。 接下來,將其綁定到與 GridView 相同的 ObjectDataSource 控制項。 與 GridView 一樣,BoundField 會被加入到 ObjectDataSource 的 Select 方法所傳回物件中的每個屬性的 DetailsView 中。 唯一的區別是 DetailsView 的 BoundFields 是水平佈局而不是垂直佈局。

將 DetailsView 新增至頁面,並將其綁定到 ObjectDataSource。

圖 13:將 DetailsView 新增至頁面,並將其綁定到 ObjectDataSource (點擊檢視完整尺寸圖片)

與 GridView 一樣,DetailsView 的 BoundFields 可以進行調整,以提供由 ObjectDataSource 傳回的資料的更自訂的顯示。 圖 14 顯示了設定 BoundFields 和 CssClass 屬性以使其外觀與 GridView 範例類似後的 DetailsView。

暸解視圖顯示單一記錄

圖 14:DetailsView 顯示單一記錄(點擊以查看全尺寸圖片

請注意,DetailsView 僅顯示其資料來源傳回的第一筆記錄。 為了讓使用者能夠逐一瀏覽所有記錄,我們必須為 DetailsView 啟用分頁功能。 為此,請返回 Visual Studio,然後在 DetailsView 的智慧標籤中勾選“啟用分頁”複選框。

在「DetailsView」控制項中啟用分頁

圖 15:在 DetailsView 控制項中啟用分頁功能 (點擊查看全尺寸圖片)

啟用分頁後,詳細資料檢視讓使用者可以查看任何產品。

圖 16:啟用分頁功能時,詳細資訊檢視允許使用者查看任一產品 (點擊可查看全尺寸影像)

我們將在以後的教學中更多地討論分頁。

更靈活的佈局,單次顯示一筆記錄

DetailsView 在如何顯示從 ObjectDataSource 傳回的每筆記錄方面非常嚴格。 我們可能想要更靈活的資料檢視。 例如,與其將產品名稱、類別、供應商、價格及停產資訊分別顯示在不同列中,我們可能希望在 <h4> 標題中顯示產品名稱和價格,而類別和供應商資訊則以較小字體顯示在名稱和價格下方。 我們可能不需要在值旁展示屬性名稱(例如產品、類別等)。

FormView 控制項提供了這種程度的自訂。 FormView 不使用欄位 (像 GridView 和 DetailsView 那樣),而是使用範本,它允許混合使用 Web 控制項、靜態 HTML 和資料綁定語法。 如果您熟悉 ASP.NET 1.x 中的 Repeater 控件,則可以將 FormView 視為顯示單一記錄的 Repeater。

將 FormView 控制項新增至 SimpleDisplay.aspx 頁面的設計圖面。 最初,FormView 顯示為灰色區塊,通知我們至少需要提供控制項的 ItemTemplate

FormView 必須包含 ItemTemplate

圖 17:FormView 必須包含一個 ItemTemplate (按一下查看全尺寸影像)

您可以透過 FormView 的 smart tag,將 FormView 直接綁定到資料源控制中。這個 smart tag 會自動建立一個預設的 ItemTemplate,以及 EditItemTemplateInsertItemTemplate,如果設定了 ObjectDataSource 控制項的 InsertMethodUpdateMethod 屬性。 但是,對於本範例,我們將資料綁定到 FormView,並手動指定其 ItemTemplate。 首先將 FormView 的 DataSourceID 屬性設定為 ObjectDataSource 控制項的 ID。 接下來,建立 ItemTemplate,使其在 <h4> 元素中顯示產品名稱和價格,並在下面以較小的字體顯示類別和發貨人名稱。

<asp:FormView ID="FormView1" runat="server"
  DataSourceID="ObjectDataSource1" EnableViewState="False">
    <ItemTemplate>
        <h4><%# Eval("ProductName") %>
          (<%# Eval("UnitPrice", "{0:c}") %>)</h4>
        Category: <%# Eval("CategoryName") %>;
        Supplier: <%# Eval("SupplierName") %>
    </ItemTemplate>
</asp:FormView>

第一個產品(Chai)顯示為自訂格式

圖 18:第一款產品 Chai 以客製化格式顯示 (點擊可看大圖)

<%# Eval(propertyName) %> 是資料綁定語法。 此方法傳回目前綁定到 FormView 控制項的物件的指定屬性值。 請參閱 Alex Homer 的文章 ASP.NET 2.0 中的簡化和擴充資料綁定語法,以了解有關資料綁定細節的更多資訊。

與DetailsView 一樣,FormView 只會顯示從ObjectDataSource 傳回的第一筆記錄。 您可以在 FormView 中啟用分頁,以允許使用者逐一瀏覽產品。

摘要

使用 ASP.NET 2.0 的 ObjectDataSource 控制項,無需編寫一行程式碼即可存取和顯示業務邏輯層中的資料。 ObjectDataSource 呼叫類別的指定方法並傳回結果。 這些結果可以顯示在綁定到 ObjectDataSource 的資料 Web 控制項中。 在本教學中,我們研究了將 GridView、DetailsView 和 FormView 控制項綁定到 ObjectDataSource。

到目前為止,我們目前只知道如何使用 ObjectDataSource 來調用無參數的方法,但如果我們想調用需要輸入參數的方法,例如 ProductBLL 類別中的 GetProductsByCategoryID(categoryID),該怎麼辦? 為了呼叫需要一個或多個參數的方法,我們必須設定 ObjectDataSource 以指定這些參數的值。 我們將在下一個教學課程中看到如何實現這一點。

快樂程式!

深入閱讀

有關本教學課程中討論的主題的更多信息,請參閱以下資源:

  • 建立您自己的資料來源控制項
  • ASP.NET 2.0 的 GridView 範例
  • ASP.NET 2.0 中的主題
  • 伺服器端樣式使用主題
  • 如何透過程式應用 ASP.NET 主題

關於作者

斯科特·米切爾,七本 ASP/ASP.NET 書籍和 4GuysFromRolla.com 創始人的作者,自1998年以來一直與Microsoft Web 技術合作。 史考特是一名獨立顧問、培訓師和作家。 他的最新著作是《Sams Teach Yourself ASP.NET 2.0 in 24 Hours》。 可以透過 mitchell@4GuysFromRolla.com 聯絡他。

特別感謝

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

下一步