ASP.NET 服务器控件GridView数据源 ASP.NET 包含一些数据源控件,这些数据源控件允许您使用不同类型的数据源,如数据库、XML 文件或中间层业务对象。数据源控件连接到数据源,从中检索数据,并使得其他控件可以绑定到数据源而无需代码。数据源控件还支持修改数据。 本主题提供有关 ASP.NET 中不同类型的数据源控件的信息。数据源控件模型是可扩展的,因此您还可以创建自己的数据源控件,实现与不同数据源的交互,或为现有的数据源提供附加功能。


1.       ASP.NET服务器控件使用之GridView数据源ObjectDataSource

本教程不介绍服务器端控件的呈现,事件处理,状态等理论知识,只介绍服务器端控件的使用操作,如果您对服务器控件的知识感兴趣,请参阅《ASP.NET服务器控件高级编程》

 

1.1         数据源概述


1.1.1                 概述

ASP.NET 包含一些数据源控件,这些数据源控件允许您使用不同类型的数据源,如数据库、XML 文件或中间层业务对象。数据源控件连接到数据源,从中检索数据,并使得其他控件可以绑定到数据源而无需代码。数据源控件还支持修改数据。

本主题提供有关 ASP.NET 中不同类型的数据源控件的信息。数据源控件模型是可扩展的,因此您还可以创建自己的数据源控件,实现与不同数据源的交互,或为现有的数据源提供附加功能。

1.1.2                 数据源控件比较

.NET Framework 包含支持不同数据绑定方案的数据源控件。下表描述了内置的数据源控件。

数据源控件

说明

ObjectDataSource

允许您使用业务对象或其他类,以及创建依赖中间层对象管理数据的 Web 应用程序。支持对其他数据源控件不可用的高级排序和分页方案。

SqlDataSource

允许您使用 Microsoft SQL Server、OLE DB、ODBC 或 Oracle 数据库。与 SQL Server 一起使用时支持高级缓存功能。当数据作为 DataSet 对象返回时,此控件还支持排序、筛选和分页。

AccessDataSource

允许您使用 Microsoft Access 数据库。当数据作为 DataSet 对象返回时,支持排序、筛选和分页。

XmlDataSource

 

允许使用 XML 文件,特别适用于分层的 ASP.NET 服务器控件,如 TreeView 或 Menu 控件。支持使用 XPath 表达式来实现筛选功能,并允许您对数据应用 XSLT 转换。XmlDataSource 允许您通过保存更改后的整个 XML 文档来更新数据。

SiteMapDataSource

结合 ASP.NET 站点导航使用。有关更多信息,请参见 ASP.NET 站点导航概述。

 

本文主要介绍ObjectDataSource作为GridView的数据源。

 

1.1.       ObjectDataSource控件

 

1.1.1.概述

ASP.NET ObjectDataSource 控件表示具有数据检索和更新功能的中间层对象。作为数据绑定控件(如 GridView、FormView 或 DetailsView 控件)的数据接口,ObjectDataSource 控件可以使这些控件在 ASP.NET 网页上显示和编辑中间层业务对象中的数据。

1.1.2.检索和修改数据

大多数 ASP.NET 数据源控件,如 SqlDataSource,都在两层应用程序层次结构中使用。在该层次结构中,表示层(ASP.NET 网页)可以与数据层(数据库和 XML 文件等)直接进行通信。但是,常用的应用程序设计原则是,将表示层与业务逻辑相分离,而将业务逻辑封装在业务对象中。这些业务对象在表示层和数据层之间形成一层,从而生成一种三层应用程序结构。ObjectDataSource 控件通过提供一种将相关页上的数据控件绑定到中间层业务对象的方法,为三层结构提供支持。在不使用扩展代码的情况下,ObjectDataSource 使用中间层业务对象以声明方式对数据执行选择、插入、更新、删除、分页、排序、缓存和筛选操作。

ObjectDataSource 控件使用反射调用业务对象的方法,以对数据执行选择、更新、插入和删除操作。设置 ObjectDataSource 控件的 TypeName 属性来指定要用作源对象的类名称。有关如何创建要与 ObjectDataSource 控件一起使用的源数据对象的详细信息,请参见创建 ObjectDataSource 控件源对象。

 

1.1.3.对ObjectDataSource控件使用参数

ObjectDataSource 控件基于 SelectMethod、InsertMethod、UpdateMethod 或 DeleteMethod 属性中所标识的方法名称以及组成业务对象方法签名的参数名来调用业务对象方法。在业务对象中创建方法时,必须确保业务对象方法所接受的参数名和类型与 ObjectDataSource 控件传递的参数名和类型匹配。(参数顺序并不重要。)

使用参数

同所有的数据源控件一样,ObjectDataSource 控件在运行时接受输入参数,并在参数集合中对参数进行管理。每一项数据操作都有一个相关的参数集合。对于选择操作,可以使用 SelectParameters 集合;对于更新操作,可以使用 UpdateParameters 集合,依此类推。

1.1.4.标识排序和分页参数

除了为 Select 业务对象方法指定 SelectParameters 对象之外,还可以包括排序和分页参数。这样您就可以对数据源对象中的数据进行排序,并将从数据源对象返回的结果限定为只返回所请求的数据页。

标识排序参数

使用 ObjectDataSource 控件的 SortParameterName 属性,可以为 Select 业务对象方法指定排序参数。SortParameterName 属性标识用于向业务对象方法传递排序列名称的参数名称。该参数为类型字符串。

 

某些数据绑定控件(例如 GridView 控件)可以自动向 ObjectDataSource 控件传递排序参数。在将支持排序的数据绑定控件绑定到 ObjectDataSource 控件时,该数据绑定控件将传递一个排序表达式,标识要用于对结果进行排序的数据列。例如,GridView 控件通过其 SortExpression 属性传递排序值。ObjectDataSource 控件基于为其传递的排序表达式,设置由 SortParameterName 属性所标识的参数的值。排序表达式可指定一个以上的列;指定多个列时,列名以逗号分隔。若要指定按降序排序,可以在排序表达式的排序列名称后加上 DESC 修饰符。例如,对于将 LastName 和 FirstName 列标识为排序依据列的排列表达式,使用“LastName, FirstName”可以按升序排序,使用“LastName, FirstName DESC”可以按降序排序。

标识分页参数

可以为 Select 方法指定其他参数,标识要返回的数据页。ObjectDataSource 控件支持两个标识分页参数的属性:

l  StartRowIndexParameterName 属性,标识在业务对象的 Select 方法中用于指定数据页起始行的参数的名称。

l  MaximumRowsParameterName 属性,标识在业务对象的 Select 方法中用于指定数据页中的行数的参数名称。

StartRowIndexParameterName 和 MaximumRowsParameterName 属性所标识的参数都是 Int32 类型。

1.1.5.创建ObjectDataSource控件源对象

ObjectDataSource 控件的源对象根据 ObjectDataSource 控件的请求在基础数据源中检索数据并执行更新。ObjectDataSource 控件的源对象可以是 ObjectDataSource 控件可创建其实例的任何类,或者是公开 ObjectDataSource 控件可调用的公共 static(在 Microsoft Visual Basic 中为 Shared)方法的任何类。

对象创建

ObjectDataSource 控件将创建源对象的实例,调用指定的方法并释放位于单个请求范围内的所有对象实例(如果对象具有实例方法而不是 static 方法(在 Visual Basic 中为 Shared))。因此,对象必须是无状态的。也就是说,源对象应获取并释放单个请求范围内所有必需的资源。

指定类构造函数

如果 ObjectDataSource 控件的源对象公开可调用的公共 static 方法(在 Visual Basic 中为 Shared)来检索和修改数据,则 ObjectDataSource 控件将直接调用这些方法。如果 ObjectDataSource 控件必须创建源对象的实例才能执行方法调用,则该对象必须包含一个不带参数的公共构造函数。ObjectDataSource 控件在创建源对象的新实例时将调用此构造函数。

如果源对象不包含不带参数的公共构造函数,则可以按照本主题前面“对象创建”中的讨论在 ObjectCreating 事件中创建 ObjectDataSource 控件要使用的源对象的实例

指定对象方法

ObjectDataSource 控件的源对象可以包含任意数量的用于选择、插入、更新或删除数据的方法。ObjectDataSource 控件根据方法的名称(使用 ObjectDataSource 控件的 SelectMethod、InsertMethod、UpdateMethod 或 DeleteMethod 属性以及选定操作的相关参数集合中的参数名称进行标识)调用这些方法。有关详细信息,请参见对 ObjectDataSource 控件使用参数。

 

此外,源对象还可以包含可选的 SelectCount 方法(由 ObjectDataSource 控件使用 SelectCountMethod 属性进行标识),该方法返回数据源中对象总数的计数。ObjectDataSource 控件在调用 Select 方法后将调用 SelectCount 方法,以在数据源中检索在分页时使用的总记录数。

 

 

1.2.       演练ObjectDataSource控件

创建新的网站

1.      在“文件”菜单中,指向“新建”,选择“网站”。

  

2.      在“新建网站”对话框中,选择“ASP.NET 网站”。

 

 

3.      在“语言”列表中,选择 Visual C#,再单击“确定”。

 

4.      在“位置”框中,保留选定的默认 HTTP,然后输入网站根目录的位置,使用“浏览”导航及创建新的文件夹(如果需要)。单击“确定”。

5.      网站项目将打开,并显示 Default.aspx 网页。

 

6.      在“查看”菜单上,选择“设计器”。

打开页面Default.aspx的代码区(点击设计器左下角的 )

替换为以下代码 

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default"  Debug="true"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>无标题页</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

     <h3>ObjectDataSource Example</h3>

      <asp:Label id="Msg" runat="server" ForeColor="Red" />

      <asp:ObjectDataSource 

        ID="EmployeesObjectDataSource" 

        runat="server" 

        TypeName="Employee" 

        SortParameterName="SortColumns"

        EnablePaging="true"

        SelectCountMethod="SelectCount"

        StartRowIndexParameterName="StartRecord"

        MaximumRowsParameterName="MaxRecords" 

        SelectMethod="GetAllEmployees" >

      </asp:ObjectDataSource>

      <table cellspacing="10">

        <tr>

          <td valign="top">

            <asp:GridView ID="EmployeesGridView" 

              DataSourceID="EmployeesObjectDataSource" 

              AutoGenerateColumns="False"

              AllowSorting="True"

              AllowPaging="True"

              PageSize="2"

              DataKeyNames="Employee_ID" 

              RunAt="server" >

              <HeaderStyle backcolor="lightblue" forecolor="black"/>

              <Columns>                

                <asp:ButtonField Text="Details
"

                                 HeaderText="Show Details"

                                 CommandName="Select"/>  

                <asp:BoundField DataField="Employee_ID" HeaderText="Employee ID" SortExpressinotallow="Employee_ID" />

                <asp:BoundField DataField="Employee_Name"  HeaderText="Employee Name" SortExpressinotallow="Employee_Name" />

                <asp:BoundField DataField="Age"   HeaderText="Age" SortExpressinotallow="Age" />                    

              </Columns>                

            </asp:GridView>            

          </td>

          <td valign="top">                

</td>                

        </tr>            

      </table>

    </div>

    </form>

</body>

</html>

         ObjectDataSource的TypeName属性指定控件源对象。

2.         SelectMethod指明查询时调用的方法,即填充GridView的方法,该方法返回一个DataTable

3.         SortParameterName属性标识用于向业务对象方法GetAllEmployees传递排序列名称的参数名称

SortParameterName参数传递的流程

asp:BoundField标签属性SortExpression指明的排序字段à SortParameterName指定的参数名称 à SelectMethod属性指定的方法。

4.         StartRowIndexParameterName 属性,标识在业务对象的 Select 方法中用于指定数据页起始行的参数的名称。

5.         MaximumRowsParameterName 属性,标识在业务对象的 Select 方法中用于指定数据页中的行数的参数名称。

6.         asp:GridView控件的DataSourceID指明它的数据源是EmployeesObjectDataSource

创建ObjectDataSource控件源对象

1.         在解决方案资源管理器中选择项目网站(以“http://”开头)。右键单击并选择“添加新项”。

  

2.         在“添加新项”对话框中,选择“类”,键入 Employee.cs 作为文件名,然后单击“添加”。

 

3.         在询问“是否要将该类放在‘App_Code’文件夹中”的消息框中,选择“是”。新文件将被添加到项目中并在 Visual Studio 中自动打开。

 

4.         在web.config中配置数据库连接

1)         什么是web.config

可扩展的基础结构是   ASP.NET   配置系统的一大特色,该基础结构使您可以在最初部署   ASP.NET   应用程序时定义配置设置,以便可以随时添加或修改这些配置设置,同时对运作着的   Web   应用程序和服务器产生的影响也将被减至最小。

2)         配置连接

在web.config的<configuration></configuration>下加上

 


<connectionStrings>

<add name="ConnectionString" connectionString="Data Source=HCDB;Persist Security Info=True;User ID=huchen;Password=huchen;Unicode=True" providerName="System.Data.OracleClient"/>

</connectionStrings>

 

    其中Data Source是指tns中的Host String, User ID是oracle登陆用户名,Password是oracle登陆密码。providerName是数据提供者。

5.         在Oracle数据库中事例创建表


 

create table EMPLOYEE_TABLE_2


(


  EMPLOYEE_ID    NUMBER,


  EMPLOYEE_NAME  VARCHAR2(20),


  AGE            NUMBER,


  DEPARTMENT_ID  NUMBER,


  PROJECT_ID     NUMBER,


  LOGIN_ID       VARCHAR2(20),


  LOGIN_PASSWORD VARCHAR2(20)


)


tablespace USERS


  pctfree 10


  initrans 1


  maxtrans 255


  storage


  (


    initial 64K


    minextents 1


    maxextents unlimited


  );

6.         将 Employee.cs 的默认代码替换为以下代码:


using System;

using System.Data;

using System.Data.OracleClient;

using System.Configuration;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

/// <summary>

///Employee 的摘要说明

/// </summary>

public class Employee


  {


    private string _connectionString;


    public Employee()


{

//初始化oracle连接


      Initialize();


    }


    public void Initialize()


    {


      // Initialize data source. Use "Northwind" connection string from configuration.


      if (ConfigurationManager.ConnectionStrings["ConnectionString"] == null ||


          ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString.Trim() == "")


      {


        throw new Exception("A connection string named 'ConnectionString' with a valid connection string " + 


                            "must exist in the <connectionStrings> configuration section for the application.");


      }


      _connectionString = 


        ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;


    }


   

/// <summary>

///  Select all employees.

/// </summary>

/// <param name="sortColumns">排序字段,由ObjectDataSource传入</param>

/// <param name="startRecord">分页后当页的初始记录号</param>

/// <param name="maxRecords">每页显示记录数,由GridView的PageSize属性传入///</param>

/// <returns>内存中的数据表</returns>


    public DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords)


    {


      VerifySortColumns(sortColumns);


      string sqlCmd = "SELECT Employee_ID, Employee_Name, Age, Login_ID, Login_Password FROM employee_table_2 ";


      if (sortColumns.Trim() == "")


        sqlCmd += "ORDER BY Employee_ID";


      else


        sqlCmd += "ORDER BY " + sortColumns;


      OracleConnection  conn = new OracleConnection(_connectionString);


      OracleDataAdapter da   = new OracleDataAdapter(sqlCmd, conn);


      DataSet ds = new DataSet();


      try


      {


        conn.Open();


        da.Fill(ds, startRecord, maxRecords, "Employees");        


      }


      catch (OracleException e)


      {


        // Handle exception.


      }


      finally


      {


        conn.Close();


      }


      return ds.Tables["Employees"];


}


 


    public int SelectCount()


    {


        OracleConnection conn = new OracleConnection(_connectionString);


        OracleCommand cmd = new OracleCommand("SELECT COUNT(*) FROM employee_table_2", conn);


        int result = 0;


        try


        {


            conn.Open();


            result = Convert.ToInt32(cmd.ExecuteScalar());


        }


        catch (OracleException e)


        {


            // Handle exception.


        }


        finally


        {


            conn.Close();


        }


        return result;


    }


    ////////////


    //// Verify that only valid columns are specified in the sort expression to avoid /////a SQL Injection attack.


    private void VerifySortColumns(string sortColumns)


    {


      if (sortColumns.ToLowerInvariant().EndsWith(" desc"))


        sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);


      string[] columnNames = sortColumns.Split(',');


      foreach (string columnName in columnNames)


      {


        switch (columnName.Trim().ToLowerInvariant())


        {


          case "employee_id":


            break;


          case "employee_name":


            break;


          case "age":


            break;


          case "":


            break;


          default:


            throw new ArgumentException("SortColumns contains an invalid column name.");


            break;


        }


      }


    }


}

运行应用程序

    把Default.aspx设为起始页,按 F5 以边运行边调试,或按 CTRL + F5 以运行而不调试,然后查看报表。