使用 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 充当代理,用于处理其他一些对象。 若要配置 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 控件

首先打开BasicReporting文件夹中的页面SimpleDisplay.aspx,切换到“设计”视图,然后将 ObjectDataSource 控件从工具箱拖到页面的设计图面上。 ObjectDataSource 在设计图面上显示为灰色框,因为它不生成任何标记;它只是通过从指定对象调用 方法来访问数据。 ObjectDataSource 返回的数据可由数据 Web 控件显示,例如 GridView、DetailsView、FormView 等。

注意

或者,可以先将数据 Web 控件添加到页面,然后从其智能标记 <中选择下拉列表中的“新建数据源> ”选项。

若要指定 ObjectDataSource 的基础对象以及该对象的方法如何映射到 ObjectDataSource,请单击 ObjectDataSource 智能标记中的“配置数据源”链接。

单击智能标记中的“配置数据Source Link

图 3:单击智能标记中的配置数据Source Link (单击以查看全尺寸图像)

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

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

指定要与 ObjectDataSource 控件一起使用的对象

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

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

从 SELECT 选项卡中选择用于返回数据的方法

图 5:从 SELECT 选项卡选择用于返回数据的方法 (单击以查看全尺寸图像)

手动配置 ObjectDataSource

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

从工具箱 SimpleDisplay.aspx向设计图面添加 GridView 控件。 从 GridView 的智能标记中,选择我们在步骤 1 中添加的 ObjectDataSource 控件。 这会在 GridView 中自动为 ObjectDataSource Select 方法 (数据返回的每个属性(即 Products DataTable) 定义的属性)创建一个 BoundField。

GridView 已添加到页面并绑定到 ObjectDataSource

图 6:已将 GridView 添加到页面并绑定到 ObjectDataSource (单击以查看全尺寸图像)

然后,可以通过单击智能标记中的“编辑列”选项来自定义、重新排列或删除 GridView 的 BoundFields。

通过“编辑列”对话框管理 GridView 的 BoundFields

图 7:通过“编辑列”对话框管理 GridView 的 BoundFields (单击以查看全尺寸图像)

请花点时间修改 GridView 的 BoundFields,删除 、ProductIDSupplierIDCategoryIDUnitsInStockQuantityPerUnitUnitsOnOrderReorderLevel BoundFields。 只需从左下角的列表中选择 BoundField,然后单击红色 X) (删除按钮即可删除它们。 接下来,通过选择这些 BoundFields UnitPrice 并单击向上箭头,重新排列 BoundField,使 CategoryNameSupplierName BoundField 位于 BoundField 前面。 将 HeaderText 其余 BoundFields 的属性分别设置为 ProductsCategorySupplierPrice。 接下来,通过将 BoundField 的 PriceHtmlEncode 属性设置为 False,将其 DataFormatString 属性 {0:c}设置为 ,将 BoundField 设置为货币。 最后,通过/ItemStyleHorizontalAlign 属性将 水平对齐 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 控件的 Skin 文件,指示默认 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 文件夹 (单击以查看全尺寸图像)

这将在名为 GridView 的 App_Themes 文件夹中创建一个新的主题,其中包含外观文件 GridView.skin

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 添加另一个 Skin,我们将很快使用一个数据 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 的 BoundField 是水平布局的,而不是垂直布局的。

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

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

与 GridView 一样,可以调整 DetailsView 的 BoundFields,以提供 ObjectDataSource 返回的数据的更自定义的显示。 图 14 显示了在将 BoundFields 和 CssClass 属性配置为使其外观类似于 GridView 示例之后的 DetailsView。

DetailsView 显示单个记录

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

请注意,DetailsView 仅显示其数据源返回的第一条记录。 若要允许用户逐一遍历所有记录,我们必须为 DetailsView 启用分页。 为此,请返回到 Visual Studio 并检查 DetailsView 的智能标记中的“启用分页”复选框。

在 DetailsView 控件中启用分页

图 15:在 DetailsView 控件中启用分页 (单击以查看全尺寸图像)

启用分页后,DetailsView 允许用户查看任何产品

图 16:启用分页后,DetailsView 允许用户查看任何产品 (单击以查看全尺寸图像)

我们将在以后的教程中详细介绍分页。

一次显示一条记录的更灵活的布局

DetailsView 在显示从 ObjectDataSource 返回的每条记录的方式上非常严格。 我们可能需要更灵活的数据视图。 例如,我们可能希望在标题中 <h4> 显示产品名称和价格,而不是在单独的行中分别显示产品名称、类别、供应商、价格和停产信息,并在名称和价格下方以较小的字号显示类别和供应商信息。 我们可能不会考虑在值旁边显示属性名称 (Product、Category 等) 。

FormView 控件提供此级别的自定义。 FormView 使用模板(允许混合使用 Web 控件、静态 HTML 和数据绑定语法),而不是像 GridView 和 DetailsView 那样) (字段。 如果您熟悉 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 控件的当前对象的指定属性的值。 有关数据绑定的详细信息,请参阅 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 配置为指定这些参数的值。 我们将在 下一教程中了解如何完成此操作。

编程愉快!

深入阅读

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

关于作者

Scott Mitchell 是七本 ASP/ASP.NET 书籍的作者, 4GuysFromRolla.com 的创始人,自 1998 年以来一直从事 Microsoft Web 技术工作。 Scott 担任独立顾问、培训师和作家。 他的最新书是 山姆斯在24小时内 ASP.NET 2.0自学。 可以在 上联系 mitchell@4GuysFromRolla.com他, 也可以通过他的博客联系到他,该博客可在 http://ScottOnWriting.NET中找到。

特别感谢

本教程系列由许多有用的审阅者查看。 本教程的首席审阅者是希尔顿·吉森诺。 有兴趣查看我即将发布的 MSDN 文章? 如果是,请在 处放置一行 mitchell@4GuysFromRolla.com