使用 ObjectDataSource 顯示資料 (C#)

作者 :Scott Mitchell

下載 PDF

本教學課程會探討 ObjectDataSource 控件 使用這個控件,您可以系結從上一個教學課程中建立的 BLL 擷取的數據,而不需要撰寫一行程序代碼!

簡介

完成應用程式架構和網站版面配置后,我們即可開始探索如何完成各種常見的數據和報告相關工作。 在先前的教學課程中,我們已瞭解如何以程序設計方式將數據從 DAL 和 BLL 系結至 ASP.NET 頁面中的數據 Web 控件。 此語法會將數據 Web 控件的 DataSource 屬性指派給要顯示的數據,然後呼叫控件的 DataBind() 方法是 ASP.NET 1.x 應用程式中所使用的模式,而且可以繼續用於您的 2.0 應用程式中。 不過,ASP.NET 2.0 的新數據源控件提供使用數據的宣告式方式。 使用這些控件,您可以系結從 一個教學課程中建立的 BLL 所擷取的數據,而不需要撰寫程式代碼行!

ASP.NET 2.0 隨附五個內建數據源控件 SqlDataSourceAccessDataSourceObjectDataSourceXmlDataSourceSiteMapDataSource ,但您可以視需要建置自己的 自定義數據源控件。 由於我們已開發教學課程應用程式的架構,因此我們將針對 BLL 類別使用 ObjectDataSource。

ASP.NET 2.0 包含五個 Built-In 數據源控件

圖 1:ASP.NET 2.0 包含五個 Built-In 數據源控件

ObjectDataSource 可作為 Proxy 來處理其他物件。 若要設定 ObjectDataSource,我們會指定此基礎物件及其方法如何對應至 ObjectDataSource 的 SelectInsertUpdateDelete 方法。 一旦指定這個基礎物件及其對應至 ObjectDataSource 的方法之後,就可以將 ObjectDataSource 系結至數據 Web 控件。 ASP.NET 隨附許多數據 Web 控件,包括 GridView、DetailsView、RadioButtonList 和 DropDownList 等等。 在頁面生命週期中,數據 Web 控件可能需要存取它所系結的數據,這會藉由叫用其 ObjectDataSource 的 Select 方法來完成;如果數據 Web 控件支援插入、更新或刪除,可能會對其 ObjectDataSource 的 InsertUpdateDelete 方法進行呼叫。 然後,ObjectDataSource 會將這些呼叫路由至適當的基礎物件方法,如下圖所示。

ObjectDataSource 做為 Proxy

圖 2:ObjectDataSource 做為 Proxy (按兩下即可檢視完整大小的影像)

雖然 ObjectDataSource 可用來叫用方法來插入、更新或刪除數據,但讓我們只專注於傳回數據;未來的教學課程將會探索如何使用 ObjectDataSource 和數據 Web 控件來修改數據。

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

從開啟 SimpleDisplay.aspx 資料夾中的頁面 BasicReporting 開始,切換至 [設計] 檢視,然後將 ObjectDataSource 控件從 [工具箱] 拖曳至頁面的設計介面。 ObjectDataSource 在設計介面上顯示為灰色方塊,因為它不會產生任何標記;只要從指定的物件叫用 方法,即可存取數據。 ObjectDataSource 傳回的數據可由數據 Web 控件顯示,例如 GridView、DetailsView、FormView 等等。

注意

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

若要指定 ObjectDataSource 的基礎物件,以及該物件的方法如何對應至 ObjectDataSource,請按下 ObjectDataSource 智慧標記中的 [設定數據源] 連結。

從智慧標記按兩下 [設定資料] Source Link

圖 3:按兩下 [智慧標記] 中的 [設定資料 Source Link (按兩下即可檢視完整大小的映像)

這會顯示 [設定數據源精靈]。 首先,我們必須指定 ObjectDataSource 要使用的物件。 如果核取 [僅顯示資料元件] 複選框,此畫面上的下拉式清單只會列出已使用 DataObject 屬性裝飾的物件。 目前我們的清單包含具型別數據集中的 TableAdapters,以及我們在上一個教學課程中建立的 BLL 類別。 如果您忘記將 屬性新增 DataObject 至商業規則層類別,您將不會在此清單中看到這些類別。 在此情況下,請取消核取 [只顯示數據元件] 複選框來檢視所有物件,其中應該包含 BLL 類別 (以及 DataTables、DataRows 等具類型 DataSet 中的其他類別) 。

從這個第一個畫面中, ProductsBLL 從下拉式清單中選擇 類別,然後按 [下一步]。

指定要搭配 ObjectDataSource 控制件使用的物件

圖 4:指定要與 ObjectDataSource 控件搭配使用的物件, (按兩下即可檢視完整大小的影像)

精靈中的下一個畫面會提示您選取 ObjectDataSource 應該叫用的方法。 下拉式清單會列出這些方法,這些方法會傳回從上一個畫面選取的物件中的數據。 在這裡,我們會看到 GetProductByProductIDGetProductsGetProductsByCategoryIDGetProductsBySupplierIDGetProducts從下拉式清單中選取方法,然後按兩下 [完成] (如果您已將 新增DataObjectMethodAttributeProductBLL上一個教學課程所示的方法,則預設會選取此選項) 。

從 [選取] 索引標籤選擇傳回數據的方法

圖 5:選擇從 SELECT 索引標籤傳回數據的方法, (按兩下即可檢視大小完整的影像)

手動設定 ObjectDataSource

ObjectDataSource 的 [設定數據源] 精靈提供快速的方式來指定它所使用的物件,以及建立物件叫用方法的關聯。 不過,您可以透過其屬性設定 ObjectDataSource,無論是透過 屬性視窗 或直接在宣告式標記中。 只要將 TypeName 屬性設定為要使用的基礎物件類型,以及 SelectMethod 擷取數據時要叫用的方法。

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

即使您偏好設定數據源精靈,有時候您可能需要手動設定 ObjectDataSource,因為精靈只會列出開發人員建立的類別。 如果您想要將 ObjectDataSource 系結至成員資格類別、存取使用者帳戶資訊等 .NET Framework 中的類別,或是使用 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 所傳回的每個屬性建立 BoundField (,也就是 Products DataTable 所定義的屬性) 。

GridView 已新增至頁面並系結至 ObjectDataSource

圖 6:GridView 已新增至頁面並系結至 ObjectDataSource (按兩下即可檢視完整大小的影像)

然後,您可以按兩下智慧標記中的 [編輯資料行] 選項,自定義、重新排列或移除 GridView 的 BoundFields。

透過 [編輯數據行] 對話框管理 GridView 的 BoundFields

圖 7:透過 [編輯數據行] 對話方塊管理 GridView 的 BoundFields (按兩下即可檢視完整大小的影像)

請花點時間修改 GridView 的 BoundFields,移除 ProductIDSupplierIDCategoryIDQuantityPerUnitUnitsInStockUnitsOnOrderReorderLevel BoundFields。 只要從左下方的清單中選取 BoundField,然後按兩下紅色 X) (刪除按鈕即可移除它們。 接下來,重新排列 BoundFields, CategoryName 讓 和 SupplierName BoundField 在 BoundField 之前 UnitPrice 選取這些 BoundField,然後按兩下向上箭號。 HeaderText將其餘 BoundFields 的屬性分別設定為 ProductsCategorySupplier、 和 Price。 接下來,將 Price BoundField 的 HtmlEncode 屬性設定為 False,並將其 屬性設定為 , DataFormatString 將 BoundField 格式化為 {0:c}貨幣。 最後,水平對齊 Price 右邊,並 Discontinued 透過 ItemStyle/HorizontalAlign 屬性將 中央的複選框對齊。

<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 控件明確設定這些屬性值。 較可管理的方法是使用 Theme 定義 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_Theme 資料夾 (按兩下以檢視完整大小的影像)

這會使用 Skin 檔案GridView.skin,在App_Themes名為 GridView 的資料夾中建立新的主題。

GridView 主題已新增至 App_Theme資料夾

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

將 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 定義相關屬性的預設屬性 CssClass。 讓我們為 DetailsView 新增另一個面板,這是我們很快就會使用的數據 Web 控制件。 將新的 [面板] 新增至名為 DetailsView.skin 的 DataWebControls 主題,並新增下列標記:

<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 中指定的屬性 不應該 覆寫在控件層級指定的屬性。 若要指定 [主題設定] 應該取代 控件設定,請使用 theme 屬性取代 styleSheetTheme;不幸的是,透過 theme 屬性指定的主題設定不會出現在 Visual Studio 設計視圖中。 如需主題和面板的詳細資訊 ,請參閱 ASP.NET 主題和外觀概觀 和使用 主題的伺服器端樣式 ;如需設定頁面以使用主題的詳細資訊,請參閱 如何:套用 ASP.NET 主題

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

圖 12:GridView 顯示產品名稱、類別、供應商、價格和已停止的資訊 (按兩下即可檢視大小完整的影像)

在 DetailsView 中一次顯示一筆記錄

GridView 會針對數據源控件所傳回的每個記錄顯示一個數據列,而該記錄會系結至其中。 不過,有時候,我們可能會想要顯示唯一記錄或一次只顯示一筆記錄。 DetailsView 控件提供這項功能,將呈現為 HTML<table>,其中包含兩個數據行,以及一個數據列,用於系結至控件的每個數據行或屬性。 您可以將 DetailsView 視為具有單一記錄旋轉 90 度的 GridView。

首先,在 中的 SimpleDisplay.aspxGridView 上方新增 DetailsView 控件。 接下來,將它系結至與 GridView 相同的 ObjectDataSource 控件。 如同 GridView,BoundField 會新增至 ObjectDataSource Select 方法所傳回之物件中每個屬性的 DetailsView。 唯一的差異在於 DetailsView 的 BoundFields 水平配置,而不是垂直配置。

將 DetailsView 新增至頁面,並將其系結至 ObjectDataSource

圖 13:將 DetailsView 新增至頁面,並將其系結至 ObjectDataSource (按兩下即可檢視大小完整的影像)

如同 GridView,可以調整 DetailsView 的 BoundFields,以提供 ObjectDataSource 所傳回數據的更自定義顯示。 圖 14 顯示 DetailsView 之後,其 BoundFields 和 CssClass 屬性已設定為使其外觀類似於 GridView 範例。

DetailsView 會顯示單一記錄

圖 14:D etailsView 顯示單一記錄 (按兩下即可檢視完整大小的影像)

請注意,DetailsView 只會顯示其數據源所傳回的第一筆記錄。 若要允許使用者逐步執行所有記錄,一次一筆,我們必須啟用DetailsView的分頁。 若要這樣做,請返回 Visual Studio,然後核取 DetailsView 智慧標記中的 [啟用分頁] 複選框。

在 DetailsView 控件中啟用分頁

圖 15:在 DetailsView 控件中啟用分頁 (按兩下即可檢視大小完整的影像)

啟用分頁功能后,DetailsView 可讓用戶檢視任何產品

圖 16:啟用分頁功能時,DetailsView 可讓用戶檢視任何產品 (按兩下即可檢視完整大小的影像)

我們將在未來的教學課程中進一步討論分頁。

一次顯示一筆記錄的更彈性版面配置

DetailsView 在顯示從 ObjectDataSource 傳回的每個記錄的方式中相當嚴格。 我們可能會想要更有彈性地檢視數據。 例如,我們可能想要在標題中顯示產品名稱、類別、供應商、價格和已停止的資訊,而是想要在標題中 <h4> 顯示產品名稱和價格,而類別和供應商資訊會以較小的字型大小顯示名稱與價格。 我們可能不會小心顯示 (Product、Category 等屬性名稱) 值旁邊。

FormView 控件提供這種自定義層級。 FormView 會使用範本,而不是使用 GridView 和 DetailsView 之類的 (字段) ,這允許混合使用 Web 控件、靜態 HTML 和數據系結語法。 如果您熟悉來自 ASP.NET 1.x 的 Repeater 控件,您可以將 FormView 視為顯示單一記錄的 Repeater。

將 FormView 控件新增至 SimpleDisplay.aspx 頁面的設計介面。 一開始,FormView 會顯示為灰色區塊,告知我們至少需要提供控件的 ItemTemplate

FormView 必須包含 ItemTemplate

圖 17:FormView 必須包含 ItemTemplate (按兩下即可檢視完整大小的影像)

您可以透過 FormView 的智慧標記,將 FormView 直接繫結至資料源控件,如果 ObjectDataSource 控制件的 InsertMethodUpdateMethod 屬性設定為) ,則會自動建立預設 ItemTemplate (EditItemTemplateInsertItemTemplate和 。 不過,在此範例中,我們將數據系結至 FormView 並手動指定 ItemTemplate 。 首先,將 FormView 的 DataSourceID 屬性設定為 ID ObjectDataSource 控制件 ObjectDataSource1的 。 接下來,建立 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) %>是數據系結語法。 方法 Eval 會傳回目前物件所系結至 FormView 控件的指定屬性值。 如需數據系結的詳細資訊,請參閱 ASP.NET 2.0 中的 Alex Homer 簡化和擴充數據系結語法一文。

如同 DetailsView,FormView 只會顯示從 ObjectDataSource 傳回的第一筆記錄。 您可以在 FormView 中啟用分頁,讓訪客一次逐步執行產品。

摘要

您可以從商業規則層存取和顯示數據,而不需撰寫程式代碼行,因為 ASP.NET 2.0 的 ObjectDataSource 控制件。 ObjectDataSource 會叫用類別的指定方法,並傳回結果。 這些結果可以在系結至 ObjectDataSource 的數據 Web 控件中顯示。 在本教學課程中,我們探討如何將 GridView、DetailsView 和 FormView 控件系結至 ObjectDataSource。

到目前為止,我們只會瞭解如何使用 ObjectDataSource 叫用無參數的方法,但如果我們想要叫用預期輸入參數的方法,例如 ProductBLL 類別的 GetProductsByCategoryID(categoryID)? 若要呼叫需要一或多個參數的方法,我們必須設定 ObjectDataSource 來指定這些參數的值。 我們將在 下一個教學課程中瞭解如何完成此作業。

快樂的程序設計!

深入閱讀

如需本教學課程中討論之主題的詳細資訊,請參閱下列資源:

關於作者

Scott Mitchell 是七份 ASP/ASP.NET 書籍的作者,以及 1998 年以來與 Microsoft Web 技術合作的 4GuysFromRolla.com 作者。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格來連線到 ,您可以在 找到http://ScottOnWriting.NET

特別感謝

本教學課程系列是由許多實用的檢閱者檢閱。 本教學課程的潛在客戶檢閱者是「三元」。 有興趣檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行 mitchell@4GuysFromRolla.com放在 。