本文將介紹不用寫任何代碼從BLL層中擷取資料,並綁定。
一、介紹
應用程式架構和網站頁面配置完成後,將開始學習通用的資料顯示的功能。在前幾篇文章中,我們已經學習了,如何通過編碼,從DAL或BLL擷取資料並綁定到頁面的Web控制項中。文法是這樣的:繫結控制項的DataSource屬性,然後調用DataBind()方法。這通常是asp.net1.x的做法,當然也可以在asp.net2.0繼續沿用。然而,在asp.net2.0中提供了一組新的控制項--資料來源控制項。使用這些控制項,可以很輕鬆將從BLL擷取的資料繫結到頁面,而不用寫任何代碼。
asp.net2.0內嵌了五個資料來源控制項--SqlDataSource,AccessDataSource,ObjectDataSource,XmlDataSource和SiteMapDataSource。如果需要,您也可以自訂資料來源控制項。基於我們的應用程式的架構,我們將使用ObjectDataSource來訪問BLL中的類。
ObjectDataSource作為訪問對象的代理。通過定義底層的對象來配置ObjectDataSource,並將對象的Select,Insert,Update和Delete方法和ObjectDataSource的方法一一對應起來。隨後,可以綁定該ObjectDataSource控制項到資料控制項,如:GridView,DetailsView,RadioButtonList和DropDownList等等。在整個頁面的生存周期中,資料控制項將通過觸發ObjectDataSource的Select方法完成資料的綁定;如果資料控制項支援插入、更新和刪除,將會分別調用ObjectDataSource的Insert、Update和Delete方法。然後再由ObjectDataSource調用底層對象的相應方法,如所示:
ObjectDataSource可以通過觸發不同的方法來插入、更新或刪除。本文將主要關注顯示資料,後續的文章將介紹如何應用ObjectDataSource和資料控制項來修改資料。
步驟1:添加、配置ObjectDataSource控制項
開啟BasicReporting檔案夾中的SimpleDisplay.aspx頁面,切換到設計檢視。從工具箱拖拽一個ObjectDataSource控制項到空白區。由於沒有任何配置,所以控制項呈灰色。可以通過調用特定對象的特定方法來訪問資料。ObjectDataSource的傳回值可以通過一個資料控制項顯示。
注意:也可以先添加資料控制項到頁面,然後通過選擇下拉式清單中的<New data source>來顯示資料。
單擊ObjectDataSource的Configure Data Source來指定ObjectDataSource對應的底層對象並將其方法一一對應起來。
開啟設定資料來源精靈後,首先,確定ObjectDataSource關聯的對象,如果選中“Show only data components”,下拉式清單中就只羅列被DataObject特性(attribute)修飾的類。當前環境下,只包括在強型別資料集中的TableAdapters和在上文中建立的BLL中的類。您也可以不選中來查看所有對象。
我們選擇ProductBLL類。
接下來選擇ObjectDataSource要觸發的方法。預設是擷取資料的方法。我們可以看到GetProductByProductID,GetProducts,GetProductsByCategoryID和GetProductsBySupplierID,選擇GetProducts方法,單擊完成。
手動設定ObjectDataSource
嚮導提供了一種快速的指定對象和關聯兩者方法的途徑。當然,也可以通過其屬性配置ObjectDataSource(可以直接通過屬性視窗,也可以用標識語言)。只需要指定ObjectDataSource的TypeName屬性到相關的類,並指定SelectMethod屬性來觸發相應的方法擷取資料。
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource
相對手動設定ObjectDataSource,您可能覺得使用嚮導會快很多倍,因為嚮導只羅列了用於建立的類。如果您想將.net framework中的類綁定到ObjectDataSource,比如綁定成員許可權的類,來訪問使用者的帳戶資訊,又或者表示路徑的類,來訪問檔案系統的資訊,您就需要手動設定ObjectDataSource的屬性了。
步驟2:添加一個資料控制項並綁定到ObjectDataSource
等ObjectDataSource添加並配置後,接著添加一個資料控制項用來接受ObjectDataSource方法返回的資料。任何的資料控制項都可以綁定到ObjectDataSource,下面展示了綁定ObjectDataSource的資料到:GridView,DetailsView,FormView。
綁定ObjectDataSource到GirdView
在頁面上(SimpleDisplay.aspx)添加一個GridView,選擇其資料來源為步驟1中建立的那個。這將會自動為ObjectDataSource的select方法返回的每一個屬性建立一個繫結資料行。
您可以自訂,排序或者移除GridView繫結資料行中的欄位。
花一定的事件修改GirdView中自動產生的繫結資料行,移除:ProductID,SupplierID,CategoryID,QuantityPerUnit,UnitsInStock,UnitsOnOrder和RecordLevel。只需要單擊紅叉號就可以了。通過上下箭頭按鈕,調整CategoryName和SupplierName到UnitPrice之前,然後設定Price列的HtmlEncode屬性為false,並DataFormateString為“{0:C}”以使其按貨幣格式顯示,設定Price的水平對齊為right和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>
設定統一外觀
我們這個系列的課程,盡量不用任何的控制項層級的樣式設定,而用一個外部的層疊樣式表來定義,如果需要的話。檔案Styles.css包含了DataWebControlStyle,HeaderStyle,RowStyle和AlternatingRowStyle等CSS類來修飾資料控制項的外觀。我們可以設定GridView的CssClass屬性為DataWebControlStyle,也可以分別設定其HeaderStyle,RowStyle和AlternatingRowStyle屬性的CssClass屬性。
一個更好的管理方式就是為這些資料控制項的使用一個主題。一個主題就是控制項層級的屬性設定,圖片和CSS類的集合,這些集合被應用到網站的頁面中以提供一個提供的外觀。
我們建立的主題不包含任何的圖片和CSS檔案,但包含兩個皮膚。一個皮膚就是一個檔案定義了web控制項的預設屬性。特定的我們為GridView和DetailsView定義一個皮膚檔案,以指示CssClass相關的屬性。
通過右擊項目名,單擊添加新項,選擇Skin檔案模板,命名為GridView.skin。
皮膚檔案將會被儲存成一個主題放置在App_Themes檔案夾中。由於我們沒有這樣一個檔案夾,當添加第一個skin檔案時,vs為自動為我們建立一個。只需單擊“是”就可以了。
這樣就會建立一個新的主題。
將GridView主題充命名為DataWebControls,接下來在GridView.skin檔案中輸入以下標識代碼:
<asp:GridView runat="server" CssClass="DataWebControlStyle">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
</asp:GridView>
這樣就使用DataWebControls主題為任何頁面中的任何GridView的預設屬性指定了相關的CssClass。添加另外一個Skin,命名為DetailsView.skin。同樣放在DataWebControls主題中。
<asp:DetailsView runat="server" CssClass="DataWebControlStyle">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<FieldHeaderStyle CssClass="HeaderStyle" />
</asp:DetailsView>
定義完主題後,然後就是應用主題到頁面了。一個主題基於頁來引用,或者說應用到網站的所有頁中。通過配置Web.config的<system.web>節來應用主題到網站中的所有頁:
<pages styleSheetTheme="DataWebControls" />
這就是所有關於主題(theme)的全部了。在主題中通過styleSheetTheme設定的屬性不能被在控制項層級設定的屬性所覆蓋。為了說明主題設定要優先於控制項層級的設定,使用theme屬性代替styleSheetTheme。唯一的不足就是無法在vs的設計檢視中通過theme屬性使用theme設定。
在DetailsView中一次顯示一條記錄
GridView控制項顯示綁定資料來源中的所有的記錄。這是比較耗時的,如果您只想一次顯示一條記錄的時候。然而,DetailsView提供了這個功能,它可以通過<table>的形式顯示兩列,每一行顯示了綁定到控制項的一個屬性或列。您可以這樣認為,DetailsView就是只顯示一行記錄的GridView翻轉了90度。
添加一個DetailsView控制項到頁面,並綁定其ObjectDataSource.和GridView一樣,將綁定從ObjectDataSource的Select方法返回的每一個屬性到DetailsView的繫結資料行。唯一的不同是:DetailsView的繫結資料行是水平布局的,而不是垂直布局的(GridView)。
和GridView一樣,也可以自訂DetailsView的繫結資料行來顯示特定的資料。顯示了自訂的繫結資料行和應用樣式配置後的外觀,非常相象於GridView。
你可能發現了DetailsView只顯示了資料來源中的第一條記錄。我們可以設定DetailsView的分頁,使得您可以一次一條記錄預覽資料來源中的所有記錄。通過設定DetailsView的智能標籤來設定。
我們將會在將來的課程中詳細講解分頁的一些細節。
一種更加靈活的一次顯示一條記錄的布局
DetailsView的顯示方式可能有點古板。我們可能需要一種更加靈活的顯示資料的方式。比如,相對於只是簡單的顯示產品的名字,價格,類別,供應商和打折資訊外,我們可能想讓商品的名字和價格以<h4>樣式顯示,也可能讓類別和供應商等資訊以較小的字型顯示在商品名稱和價格下面。因為我們有時候可能不太關注這些資訊。
通過FormView就可以實現上述靈活的顯示功能。但相對於GridView和DetailsView使用列,FormView使用模板,在模板裡面可以自由組合web控制項,靜態html,甚至可以寫一些資料繫結的代碼。如果您對asp.net1.x中的repeater比較熟悉,你可以把FormView想象成一個只顯示一條記錄的Repeater。
添加一個FormView到SimpleDisplay.aspx,預設情況下,呈灰色顯示,告訴我們至少要設定控制項的ItemTemplate.
您可以通過FormView的智能標籤直接繫結控制項到資料來源。這將會為您自動建立一個ItemTemplate。(如果資料來源的InsertMethod和UpdateMethod設定後,同樣為在FormView中建立InsertItemTemplate和EditItemTemplate。)在本例中,我們綁定資料到FormView並手動設定ItemTemplate。首先,設定FormView的DataSourceID屬性為ObjectDataSource的ID--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>
<%# Eval(prppertyName)%>就是用來綁定的文法。Eval方法為FormView控制項放回當前對象中的特定的屬性。
和DetailsView一樣,FormView只顯示ObjectDataSource中的第一條記錄。您同樣可以通過分頁來便利所有的記錄。
二、總結
通過asp.net2.0提供的ObjectDataSource控制項,可以讓您不用寫任何一行代碼就可以從BLL中定義的對象中擷取資料並顯示資料。通過ObjectDataSource觸發特定的方法並返回結果,這些結果可以被綁定到資料控制項。在本文中我們學習了如果綁定BObjectDataSource到GridView,DetailsView和FormView。
至此為止,我們學習了通過ObjectDataSource來觸發一個沒有參數的方法。但如果我們需要觸發一個需要輸入參數的方法,如ProductBLL中的GetProductsByCategoryID(categoryID),應該如何做呢?我們將在下次內容中介紹,如果配置ObjectDataSource,讓其能夠觸發接受一個或多個輸入參數的方法。
快樂編程!!!