April 18, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Wire Up Data-Driven Web Apps with an ASP.NET 2.0 DataSource Control

  • June 7, 2006
  • By Mark Strawmyer
  • Send Email »
  • More Articles »

DataSource controls provide declarative data binding, or put more simply, data binding without requiring you to write code. They represent back end data stores and replace the code that queries data sources and binds the results to controls with <asp:> tags. As such, they have no rendering in the user interface. DataSource controls also provide rich capabilities such as sorting, paging, filtering, updating, deleting, and inserting across data.

ASP.NET 2.0 has five DataSource controls:

  • AccessDataSource: Connects data binding controls to an Access database
  • ObjectDataSource: Connects data binding controls to data objects/components
  • SiteMapDataSource: Connects site navigation controls to site map data
  • SqlDataSource: Connects data binding controls to a SQL Server database
  • XmlDataSource: Connects data binding controls to XML data

This article focuses on the ObjectDataSource and the value it provides.

ObjectDataSource Background

N-tier applications commonly isolate the logic for talking to data sources in a data access layer. The theory behind this design is to isolate the user front end or UI from changes that may occur to the back end data store. This eliminates the dependency between the UI and the data source. As long as the data access layer does not change the interface it presents to the UI, the back end data source can change any number of times with minimal to no effect on the front end.

Interestingly, not all of the DataSource controls are designed to support an n-tier type of application. For example, the AccessDataSource and SqlDataSource controls do not allow for a separation of UI and data access. They actually do the opposite; the AccessDataSource and SqlDataSource controls create an explicit connection between the UI and the back end data store.

The ObjectDataSource (ODS), however, was created with n-tier applications in mind. It supports declarative data binding to data objects/components, which allows for use of middle-tier data access components. It supports two-way data binding through SelectMethod, InsertMethod, UpdateMethod, and DeleteMethod. It also offers optional caching of query results and parameterized operations.

The ODS has a number of properties that allow you to control its behavior. This article covers the following ODS properties:

  • TypeName: Type of the data component
  • DataObjectTypeName: Type of parameter used for calls to insert, update, and delete operations in place of individual parameters
  • SelectMethod: Method called on the data component to execute read queries
  • InsertMethod: Method called on the data component to execute inserts
  • UpdateMethod: Method called on the data component to execute updates
  • DeleteMethod: Method called on the data component to execute deletes
  • SelectParameters: Parameters for SelectMethod
  • InsertParameters: Parameters for InsertMethod
  • UpdateParameters: Parameters for UpdateMethod
  • DeleteParameters: Parameters for DeleteMethod

Although it appears simple in its function, the ODS is complex in nature. A number of subtle nuances can influence its behavior in many different ways.

Selecting Data

To demonstrate how to select data through an ObjectDataSource and display it in a GridView control, the example in this section sets the SelectMethod property on the ODS and configures a GridView.

The following sample code represents a data object component for data from the SQL Server example database. A connection string in the web.config file contains the connection string information required. For this simple example, the data component will do nothing more than query some data from the Northwind database and return it in a collection:

using System;using System.Collections;using System.Data;using System.Data.SqlClient;using System.Configuration;public class Customers{   public Customers()   {   }   public ICollection GetCustomers()   {      ArrayList al = new ArrayList();      ConnectionStringSettings cts =         ConfigurationManager.ConnectionStrings["Northwind"];      using (SqlConnection connection =         new SqlConnection(cts.ConnectionString))      {         using (SqlCommand cmd =            new SqlCommand("SELECT * FROM Customers", connection))         {            connection.Open();            using (SqlDataReader reader =               cmd.ExecuteReader(CommandBehavior.CloseConnection))            {               while (reader.Read())               {                  al.Add(new Customer(reader));               }            }            connection.Close();         }      }      return al;   }}public class Customer{   private string customerID = "";   public string CustomerID   {      get { return this.customerID; }      set { this.customerID = value; }   }   private string companyName = "";   public string CompanyName   {      get { return this.companyName; }      set { this.companyName = value;    }   public Customer(IDataReader reader)   {      this.CustomerID = reader["CustomerID"].ToString();      this.CompanyName = reader["CompanyName"].ToString();   }}

The following code provides an example declaration of an ObjectDataSource control and a grid view. The ObjectDataSource is connected to the data component and the GridView is bound to the data source. This will result in a grid being displayed with two columns of data from the Northwind database:

<div>   <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"   SelectMethod="GetCustomers" TypeName="Customers">   </asp:ObjectDataSource>/\*-</div><asp:GridView ID="GridView1" runat="server"              DataSourceID="ObjectDataSource1"></asp:GridView>

When you execute the code, you should see results similar to Figure 1.



Click here for a larger image.

Figure 1. Example ObjectDataSource Control and a Grid View

Inserting, Updating, and Deleting Data

The insert, update, and delete functionalities all behave similarly. This example uses the update functionality to demonstrate how they work, but it could just as easily be insert or delete. To be able to update data, you set the UpdateMethod property of the ObjectDataSource to the name of the data component method that you want to call. Here, you start to get into some of the many nuances of the ObjectDataSource control and its behavior. Subtle configuration changes can make a big difference in the way the ObjectDataSource behaves.

UpdateMethod Auto Wire-Up

The following code contains the ObjectDataSource declaration along with UpdateCustomer sample code to add to the Customers example in the previous section. It enables the autogenerate of the edit button on the GridView so that it will automatically build out the columns. On the ObjectDataSource, it sets the DataObjectTypeName to Customer. This will cause the GridView to automatically populate an instance of the Customer class and pass it as a parameter to the UpdateCustomer method.

Here is the Web form sample code:

<div>   <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"   SelectMethod="GetCustomers" TypeName="Customers"   DataObjectTypeName="Customer" UpdateMethod="UpdateCustomer">   </asp:ObjectDataSource></div><asp:GridView ID="GridView1" runat="server"              AutoGenerateEditButton="True"              DataSourceID="ObjectDataSource1"></asp:GridView>

Here is the sample code to include in the Customers class:

//...public static void UpdateCustomer(Customer customer){   System.Diagnostics.Debug.WriteLine(customer.CustomerID);   System.Diagnostics.Debug.WriteLine(customer.CompanyName);}

The ability to automatically populate and pass a Customer instance is a nice feature, but you can run into some functionality that may not work so well. In this case, it will pass in all the columns from the GridView into the Customer instance because the values are named the same and are all contained within the GridView. As soon as you remove fields like customerID from the actual display, the values are no longer passed in to the UpdateCustomer method through a Customer instance. Not having the customerID or the original customerID makes it difficult to know what to update. Now, you want more control.

UpdateMethod with Specified Parameters

At times, you may find that you want to control exactly which values get passed in to the update. For example, you may want to add an additional column from a drop-down list or other text box. You'll get more consistent behavior from the ObjectDataSource by following a specific pattern when using it. You should specify exactly which parameters you want to be passed in to the method call. The following code snippet demonstrates an update method with two parameters to be included in the UpdateCustomer method of the Customers class:

public static void UpdateCustomer(string customerID,                                  string companyName){   System.Diagnostics.Debug.WriteLine(customerID);   System.Diagnostics.Debug.WriteLine(companyName);}

Here is the resulting ObjectDataSource definition:

<asp:ObjectDataSource ID="ObjectDataSource1"                      runat="server" SelectMethod="GetCustomers"                      TypeName="Customers"                      UpdateMethod="UpdateCustomer">   <UpdateParameters>      <asp:FormParameter Name="customerID" Type="String" />      <asp:FormParameter Name="companyName" Type="String"/>   </UpdateParameters></asp:ObjectDataSource>

Notice that I removed the DataObjectTypeName property from the definition. Your attempt to add parameters will be ignored when that property is set, which is bound to cause you headaches during debugging.

This technique can run into some of the same problems as before, where it assumes that all of the values that you need and want to update are present in the GridView. There is a more realistic pattern that requires a little more code. It involves using the GridView_RowUpdating event. Here is the GridView definition:

<div>   <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"                         SelectMethod="GetCustomers"                         TypeName="Customers"                         UpdateMethod="UpdateCustomer">   </asp:ObjectDataSource></div><asp:GridView ID="GridView1" runat="server"              AutoGenerateEditButton="True"              DataSourceID="ObjectDataSource1"              OnRowUpdating="GridView1_RowUpdating"></asp:GridView>

Here is a revised version of the UpdateCustomers method. You'll notice that I added a third parameter representing the original customer ID:

public static void UpdateCustomer(string originalCustomerID,                                  string customerID,                                  string companyName){   System.Diagnostics.Debug.WriteLine(originalCustomerID);   System.Diagnostics.Debug.WriteLine(customerID);   System.Diagnostics.Debug.WriteLine(companyName);}

The following code belongs in the event handler of the Web form. The event allows you to take advantage of the NewValues and OldValues collections to retrieve values and use them in the update process. Set up the call to the update process and execute it:

protected void GridView1_RowUpdating(object sender,                                     GridViewUpdateEventArgs e){   ObjectDataSource1.UpdateParameters.Clear();   ObjectDataSource1.UpdateParameters.Add("customerID",      e.OldValues[0].ToString());   ObjectDataSource1.UpdateParameters.Add("companyName",      e.NewValues[1].ToString());   ObjectDataSource1.Update();   GridView1.EditIndex = -1;   e.Cancel = true;}




Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel