作者 :斯科特·米切尔
本教程介绍 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 附带了五个内置数据源控件 SqlDataSource、 AccessDataSource、 ObjectDataSource、 XmlDataSource 和 SiteMapDataSource ,但可以根据需要生成自己的 自定义数据源控件。 由于我们已经为教程应用程序开发了一个体系结构,因此我们将针对 BLL 类使用 ObjectDataSource。
图 1:ASP.NET 2.0 包括五个 Built-In 数据源控件
ObjectDataSource 充当与其他对象交互的中介。 若要配置 ObjectDataSource,请指定此基础对象及其方法如何映射到 ObjectDataSource 的 Select
、Insert
Update
和Delete
方法。 指定此基础对象并将其方法映射到 ObjectDataSource 后,我们可以将 ObjectDataSource 绑定到数据 Web 控件。 ASP.NET 附带了许多数据 Web 控件,包括 GridView、DetailsView、RadioButtonList 和 DropDownList 等。 在页面生命周期内,数据 Web 控件可能需要访问绑定数据,这可以通过调用其 ObjectDataSource 的 Select
方法来实现;如果数据 Web 控件支持插入、更新或删除,则可能会调用其 ObjectDataSource 的 Insert
、Update
或 Delete
方法。 然后,ObjectDataSource 将这些调用路由到相应的基础对象的方法,如下图所示。
图 2:ObjectDataSource 充当代理(单击以查看全尺寸图像)
虽然 ObjectDataSource 可用于调用插入、更新或删除数据的方法,但让我们专注于返回数据;将来的教程将探讨如何使用 ObjectDataSource 和数据 Web 控件来修改数据。
步骤 1:添加和配置 ObjectDataSource 控件
首先打开 SimpleDisplay.aspx
文件夹中的页面 BasicReporting
,切换到设计视图,然后将 ObjectDataSource 控件从工具箱拖动到页面的设计图面上。 ObjectDataSource 在设计图面上显示为灰色框,因为它不生成任何标记;它只需通过从指定对象调用方法来访问数据。 ObjectDataSource 返回的数据可由数据 Web 控件显示,例如 GridView、DetailsView、FormView 等。
注释
或者,可以先将数据 Web 控件添加到页面, <然后从其智能标记中选择下拉列表中的“新建数据源> ”选项。
若要指定 ObjectDataSource 的基础对象以及该对象的方法如何映射到 ObjectDataSource,请单击 ObjectDataSource 智能标记中的“配置数据源”链接。
图 3:单击智能标记中的“配置数据源链接”(单击以查看全尺寸图像)
此时会显示“配置数据源”向导。 首先,必须指定 ObjectDataSource 要使用的对象。 如果选中了“仅显示数据组件”复选框,则此屏幕上的下拉列表仅列出使用该属性修饰 DataObject
的对象。 目前,我们的列表包括 Typed DataSet 中的 TableAdapters 和我们在上一教程中创建的 BLL 类。 如果忘记将 DataObject
属性添加到业务逻辑层类,则在此列表中看不到这些属性。 在这种情况下,请取消选中“仅显示数据组件”复选框以查看所有对象,这些对象应包括 BLL 类(以及 DataTables、DataRows 等类型化数据集中的其他类)。
从此第一个屏幕中选择下拉列表中的 ProductsBLL
类,然后单击“下一步”。
图 4:指定要与 ObjectDataSource 控件一起使用的对象(单击以查看全尺寸图像)
向导中的下一个屏幕会提示你选择 ObjectDataSource 应调用的方法。 下拉列表列出那些方法,这些方法返回从上一屏幕中选择的对象中的数据。 我们在这里看到GetProductByProductID
、GetProducts
、GetProductsByCategoryID
和GetProductsBySupplierID
。
GetProducts
从下拉列表中选择该方法,然后单击“完成”(如果已将方法添加到DataObjectMethodAttribute
ProductBLL
上一教程所示的方法,则默认情况下会选中此选项)。
图 5:从 SELECT 选项卡中选择返回数据的方法(单击以查看全尺寸图像)
手动配置 ObjectDataSource
ObjectDataSource 的“配置数据源”向导提供了一种快速方法来指定它使用的对象,并关联调用对象的方法。 然而,您可以通过其属性来配置 ObjectDataSource,可以使用属性窗口或者直接在声明性标记中进行设置。 只需将 TypeName
属性设置为要使用的基础对象的类型,以及 SelectMethod
检索数据时要调用的方法。
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
即使你更喜欢“配置数据源”向导,有时可能需要手动配置 ObjectDataSource,因为向导仅列出开发人员创建的类。 如果要将 ObjectDataSource 绑定到 .NET Framework 中的类(如 Membership 类、访问用户帐户信息)或 目录类 来处理文件系统信息,则需要手动设置 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 定义的属性)。
图 6:已将 GridView 添加到页面并绑定到 ObjectDataSource(单击可查看全尺寸图像)
然后,可以通过单击智能标记中的“编辑列”选项来自定义、重新排列或删除 GridView 的 BoundFields。
图 7:通过“编辑列”对话框管理 GridView 的 BoundFields(单击以查看全尺寸图像)
花点时间修改 GridView 的 BoundFields,删除 ProductID
SupplierID
、、CategoryID
、QuantityPerUnit
UnitsInStock
、 UnitsOnOrder
和 ReorderLevel
BoundFields。 只需从左下角的列表中选择 BoundField,然后单击删除按钮(红色 X)将其删除。 接下来,重新排列 BoundField,使 CategoryName
和 SupplierName
BoundField 位于 UnitPrice
BoundField 前面,方法是选择这些 BoundField 并单击向上箭头。 将 HeaderText
剩余 BoundFields 的属性分别设置为 Products
、 Category
、 Supplier
和 Price
。 接下来,将Price
BoundField 格式化为货币形式,方法是将 BoundField 的HtmlEncode
属性设置为 False,并将DataFormatString
属性设置为{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>
图 8:GridView 的 BoundFields 已自定义(单击以查看全尺寸图像)
使用主题实现一致的外观
这些教程尽量删除任何控件级样式设置,而应尽可能使用外部文件中定义的级联样式表。 该文件Styles.css
包含DataWebControlStyle
、HeaderStyle
和 RowStyle
AlternatingRowStyle
CSS 类,这些类应用于指示这些教程中使用的数据 Web 控件的外观。 为实现这一目标,我们可以将 GridView 的CssClass
属性设置为DataWebControlStyle
,并根据HeaderStyle
调整其RowStyle
、AlternatingRowStyle
和CssClass
属性。
如果在 Web 控件上设置这些 CssClass
属性,则需要记住为每个添加到教程的每个数据 Web 控件显式设置这些属性值。 更易管理的方法是使用 Theme 定义 GridView、DetailsView 和 FormView 控件的默认 CSS 相关属性。 主题是控件级属性设置、图像和 CSS 类的集合,可应用于网站中的页面,以强制实施常见外观。
主题不包含任何图像或 CSS 文件(我们将保留样式表 Styles.css
as-is,在 Web 应用程序的根文件夹中定义),但将包含两个外观。 皮肤是一个定义 Web 控件默认属性的文件。 具体而言,我们将为 GridView 和 DetailsView 控件创建一个外观文件,用于指示默认的 CssClass
相关属性。
首先,在解决方案资源管理器中右键单击项目 GridView.skin
名称并选择“添加新项”,将新的外观文件添加到项目。
图 9:添加命名 GridView.skin
外观文件(单击以查看全尺寸图像)
需要将皮肤文件放在位于App_Themes
文件夹中的主题中。 由于我们还没有这样的文件夹,Visual Studio 在添加第一个皮肤时会友好地为我们提供创建文件夹的选项。 单击“是”以创建 App_Theme
文件夹,并将新 GridView.skin
文件放置到该文件夹。
图 10:让 Visual Studio 创建 App_Theme
文件夹(单击以查看全尺寸图像)
这将使用 Skin 文件App_Themes
在GridView.skin
名为 GridView 的文件夹中创建一个新的主题。
图 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 控件。 向 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 主题和外观概述和Server-Side 使用主题的样式的详细信息,请参阅;有关配置页面以使用主题的更多信息,请参阅如何:应用 ASP.NET 主题。
图 12:GridView 显示产品名称、类别、供应商、价格和停产信息(单击可查看全尺寸图像)
在 DetailsView 中一次显示一条记录
GridView 对数据源控件返回的每个记录显示一行。 但是,有时我们可能需要显示唯一记录或一次只显示一条记录。 DetailsView 控件提供此功能,将绑定到控件的每个列或属性呈现为包含两列和一行的 HTML 表格。 可以将 DetailsView 视为一个 GridView,其中单个记录旋转了 90 度。
首先在 GridView 上方 添加 DetailsView SimpleDisplay.aspx
控件。 接下来,将其绑定到与 GridView 相同的 ObjectDataSource 控件。 与 GridView 一样,ObjectDataSource 的 Select
方法返回的对象中的每个属性都会在 DetailsView 中添加一个 BoundField。 唯一的区别是 DetailsView 的 BoundFields 水平布局而不是垂直布局。
图 13:向页面添加 DetailsView 并将其绑定到 ObjectDataSource(单击可查看全尺寸图像)
与 GridView 一样,可以调整 DetailsView 的 BoundFields,以更个性化地显示 ObjectDataSource 返回的数据。 图 14 显示了 DetailsView 后,其 BoundFields 和 CssClass
属性已配置为使其外观类似于 GridView 示例。
图 14:DetailsView 显示单个记录(单击以查看全尺寸图像)
请注意,DetailsView 仅显示其数据源返回的第一条记录。 若要允许用户逐个浏览所有记录,必须为 DetailsView 启用分页。 为此,请返回到 Visual Studio,并选中 DetailsView 智能标记中的“启用分页”复选框。
图 15:在 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
。
图 17:FormView 必须包含一个 ItemTemplate
(单击以查看全尺寸图像)
可以通过 FormView 的智能标记将 FormView 直接绑定到数据源控件,该标记将自动创建一个默认ItemTemplate
(还会创建EditItemTemplate
和InsertItemTemplate
,如果 ObjectDataSource 控件的InsertMethod
和UpdateMethod
属性已设置)。 但是,对于此示例,让我们将数据绑定到 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>
图 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 配置为指定这些参数的值。 我们将在 下一教程中了解如何完成此作。
快乐编程!
深入阅读
有关本教程中讨论的主题的详细信息,请参阅以下资源:
关于作者
斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是 《Sams Teach Yourself ASP.NET 2.0 in 24 Hours》。 可以通过 mitchell@4GuysFromRolla.com 联系到他。
特别致谢
本教程系列由许多有用的审阅者审阅。 本教程的主要审阅者是希尔顿·吉森诺。 有兴趣查看即将发布的 MSDN 文章? 如果是这样,请给我写信。mitchell@4GuysFromRolla.com