使用 ObjectDataSource 显示数据 (C#)

作者 :斯科特·米切尔

下载 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 充当与其他对象交互的中介。 若要配置 ObjectDataSource,请指定此基础对象及其方法如何映射到 ObjectDataSource 的 SelectInsertUpdateDelete方法。 指定此基础对象并将其方法映射到 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:单击智能标记中的“配置数据源链接”(单击以查看全尺寸图像

此时会显示“配置数据源”向导。 首先,必须指定 ObjectDataSource 要使用的对象。 如果选中了“仅显示数据组件”复选框,则此屏幕上的下拉列表仅列出使用该属性修饰 DataObject 的对象。 目前,我们的列表包括 Typed DataSet 中的 TableAdapters 和我们在上一教程中创建的 BLL 类。 如果忘记将 DataObject 属性添加到业务逻辑层类,则在此列表中看不到这些属性。 在这种情况下,请取消选中“仅显示数据组件”复选框以查看所有对象,这些对象应包括 BLL 类(以及 DataTables、DataRows 等类型化数据集中的其他类)。

从此第一个屏幕中选择下拉列表中的 ProductsBLL 类,然后单击“下一步”。

指定要用于 ObjectDataSource 控件的对象

图 4:指定要与 ObjectDataSource 控件一起使用的对象(单击以查看全尺寸图像

向导中的下一个屏幕会提示你选择 ObjectDataSource 应调用的方法。 下拉列表列出那些方法,这些方法返回从上一屏幕中选择的对象中的数据。 我们在这里看到GetProductByProductIDGetProductsGetProductsByCategoryIDGetProductsBySupplierIDGetProducts从下拉列表中选择该方法,然后单击“完成”(如果已将方法添加到DataObjectMethodAttributeProductBLL上一教程所示的方法,则默认情况下会选中此选项)。

从 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 类、访问用户帐户信息)或 目录类 来处理文件系统信息,则需要手动设置 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,删除 ProductIDSupplierID、、CategoryIDQuantityPerUnitUnitsInStockUnitsOnOrderReorderLevel BoundFields。 只需从左下角的列表中选择 BoundField,然后单击删除按钮(红色 X)将其删除。 接下来,重新排列 BoundField,使 CategoryNameSupplierName BoundField 位于 UnitPrice BoundField 前面,方法是选择这些 BoundField 并单击向上箭头。 将 HeaderText 剩余 BoundFields 的属性分别设置为 ProductsCategorySupplierPrice。 接下来,将Price BoundField 格式化为货币形式,方法是将 BoundField 的HtmlEncode 属性设置为 False,并将DataFormatString 属性设置为{0:c}。 最后,通过PriceDiscontinuedItemStyle属性,将/水平对齐到右侧,并将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,并根据HeaderStyle调整其RowStyleAlternatingRowStyleCssClass属性。

如果在 Web 控件上设置这些 CssClass 属性,则需要记住为每个添加到教程的每个数据 Web 控件显式设置这些属性值。 更易管理的方法是使用 Theme 定义 GridView、DetailsView 和 FormView 控件的默认 CSS 相关属性。 主题是控件级属性设置、图像和 CSS 类的集合,可应用于网站中的页面,以强制实施常见外观。

主题不包含任何图像或 CSS 文件(我们将保留样式表 Styles.css as-is,在 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 文件App_ThemesGridView.skin名为 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 控件。 向 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 主题

GridView 显示产品名称、类别、供应商、价格和停产信息

图 12:GridView 显示产品名称、类别、供应商、价格和停产信息(单击可查看全尺寸图像

在 DetailsView 中一次显示一条记录

GridView 对数据源控件返回的每个记录显示一行。 但是,有时我们可能需要显示唯一记录或一次只显示一条记录。 DetailsView 控件提供此功能,将绑定到控件的每个列或属性呈现为包含两列和一行的 HTML 表格。 可以将 DetailsView 视为一个 GridView,其中单个记录旋转了 90 度。

首先在 GridView 上方 添加 DetailsView SimpleDisplay.aspx控件。 接下来,将其绑定到与 GridView 相同的 ObjectDataSource 控件。 与 GridView 一样,ObjectDataSource 的 Select 方法返回的对象中的每个属性都会在 DetailsView 中添加一个 BoundField。 唯一的区别是 DetailsView 的 BoundFields 水平布局而不是垂直布局。

将 DetailsView 添加到页面并将其绑定到 ObjectDataSource

图 13:向页面添加 DetailsView 并将其绑定到 ObjectDataSource(单击可查看全尺寸图像

与 GridView 一样,可以调整 DetailsView 的 BoundFields,以更个性化地显示 ObjectDataSource 返回的数据。 图 14 显示了 DetailsView 后,其 BoundFields 和 CssClass 属性已配置为使其外观类似于 GridView 示例。

DetailsView 显示单个记录

图 14:DetailsView 显示单个记录(单击以查看全尺寸图像

请注意,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 直接绑定到数据源控件,该标记将自动创建一个默认ItemTemplate(还会创建EditItemTemplateInsertItemTemplate,如果 ObjectDataSource 控件的InsertMethodUpdateMethod属性已设置)。 但是,对于此示例,让我们将数据绑定到 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 配置为指定这些参数的值。 我们将在 下一教程中了解如何完成此作。

快乐编程!

深入阅读

有关本教程中讨论的主题的详细信息,请参阅以下资源:

关于作者

斯科特·米切尔,七本 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