Implementing Object Binding in ASP.NET 2.0

Create True Enterprise-class Web Applications

LANGUAGES: C#

ASP.NET VERSIONS: 2.0

ASP.NET 2.0 has introduced a host of new data-source controls for seamlessly consuming data from a variety of data sources without writing a single line of code. To this end, ASP.NET 2.0 features new data-source controls such as SqlDataSource, ObjectDataSource, AccessDataSource, XmlDataSource, and SiteMapDataSource. Of all these controls, the most interesting and promising is the ObjectDataSource control. Why? Because it complements the n-tier application design (widely used by enterprise-class applications) by allowing you to bind the values returned by the middle-tier objects onto data-bound controls such as GridView, FormView, DetailView, and so on. This article takes a detailed look at the features of the ObjectDataSource control through examples. After reading this article you ll also understand how to bind the generic collection object returned by the middle-tier object to an ObjectDataSource control.

 

What Is Object Binding?

Object binding is the ability to declaratively bind the output of an object s method to a data-bound control (through an ObjectDataSource control) without writing any code. ObjectDataSource belongs to the family of data-source controls in ASP.NET that enables a declarative data-binding model against a variety of underlying data stores, such as SQL databases or XML. Most data-source controls encourage a two-tiered application architecture, where the presentation layer (the page) interacts directly with the back-end data provider. However, it is also common for page developers to encapsulate data retrieval (and optionally business logic) into a component object, introducing an additional layer between the presentation page and data provider. The ObjectDataSource control allows developers to structure their applications using the proven three-tiered architecture principles and still take advantage of the ease-of-use benefits of the declarative data-binding model in ASP.NET. This approach provides for clean separation and encapsulation of code, thereby eliminating the need to write data access layer code in the presentation layer.

 

The ObjectDataSource control object model is similar to the SqlDataSource control. However, instead of a ConnectionString property, ObjectDataSource exposes a TypeName property that specifies an object type (class name) to instantiate for performing data operations. Similar to the command properties of SqlDataSource, the ObjectDataSource control supports properties such as SelectMethod, UpdateMethod, InsertMethod, and DeleteMethod for specifying methods of the associated type to call to perform these data operations.

 

A Primer on ObjectDataSource Control

As previously mentioned, an ObjectDataSource control allows you to directly bind the output of the business object to a data-bound control such as a GridView or a FormView control. To enable this declarative codeless object binding, the ObjectDataSource control exposes many properties. Figure 1 outlines the important properties of the ObjectDataSource control with which you will most likely work.

 

Property

Description

CacheDuration

Gets or sets the length of time the control caches data retrieved by the data-source control.

CacheExpirationPolicy

Gets or sets the cache expiration behavior that describes the caching behavior of the data-source control. Can be set to either Absolute or Sliding.

ConvertNullToDBNull

Allows you to specify whether the null value supplied to the control should be automatically converted to DBNull.

DataObjectTypeName

Allows you to set or get the name of a class that the ObjectDataSource control uses for passing parameters.

DeleteMethod

Allows you to specify the name of the method that the ObjectDataSource control uses for the delete operation.

DeleteParameters

Read-only property that allows you to get the parameter collection used by DeleteMethod.

EnableCaching

Boolean value that allows you to specify if caching is enabled.

EnablePaging

Boolean value that allows you to specify if paging is enabled.

InsertMethod

Allows you to set or get the name of the insert method used by the ObjectDataSource control.

InsertParameters

Read-only property that allows you to get reference to the parameters used by InsertMethod.

SelectCountMethod

Allows you to specify the name of the business object method that will be used by the ObjectDataSource control to get the count of the number of rows. Note the row count is specifically used to support data-source paging.

SelectMethod

Allows you to specify the method used by the ObjectDataSource control for retrieving data.

SelectParameters

Read-only property that gets the reference to the parameters collection used by SelectMethod.

TypeName

Allows you to set or get the name of the class against which the ObjectDataSource control performs all the operations.

UpdateMethod

Allows you to get or set the name of the method used by the ObjectDataSource control for updating purposes.

UpdateParameters

Read-only property that returns the parameters collection used by UpdateMethod.

Figure 1: Important properties of the ObjectDataSource control.

 

Now that you have a general understanding of the ObjectDataSource control, let s look at an example.

 

ObjectDataSource Control Example

To better understand how the ObjectDataSource control works, let s take a look at an example that demonstrates how to create a data access layer component and then invoke its methods from an ASP.NET page.

 

First, create a new ASP.NET Web site by selecting New Web Site from the File menu in Visual Studio 2005. In the New Web Site dialog box, click the Browse button. In the Choose Location dialog box, select Local IIS in the left navigation pane and create a virtual directory named ObjectBinding under MyProjects\aspnetPro, then click Open. The location in the New Web Site dialog box should now read http://localhost/MyProjects/aspnetPro/ObjectBinding.

 

Let s split the implementation of this application into two parts:

  • Create the middle-tier class that returns the appropriate data.
  • Create an ASP.NET page with the ObjectDataSource control and bind the ObjectDataSource control to the methods of the previously created class.

 

Let s start by creating the required class.

 

Creating the Class

In this step, you ll create the required class used for returning the appropriate data from the database.

 

To create the class, select Website | Add New Item from the menu. In the Add New Item dialog box, select Class from the list of templates. Change the name of the class to Authors.cs and click Add. Now you ll get a prompt asking if you want to place the class inside the App_Code directory; answer yes. After the class is created, modify the code in the Authors.cs file to read as shown in Figure 2.

 

using System;

using System.Data.SqlClient;

using System.Data.Sql;

using System.Configuration;

using System.Collections.Generic;

public class Authors

{

 public Authors()

 {

 }

 public SqlDataReader GetSqlDataReader(string sql)

 {

   string connString =

     ConfigurationManager.ConnectionStrings["pubs"].ConnectionString;

   SqlConnection sqlConn = new SqlConnection(connString);

   sqlConn.Open();

   SqlCommand sqlCmd = sqlConn.CreateCommand();

   sqlCmd.CommandText = sql;

   // Create the SqlDataReader object and return it

   SqlDataReader reader = sqlCmd.ExecuteReader();

   return reader;

 }

 public SqlDataReader GetAuthors()

 {

   return GetSqlDataReader("Select au_id, au_lname + ' ' +

     au_fname as Name from authors");

 }

 public SqlDataReader GetTitlesByAuthors(string authorID)

 {

   return GetSqlDataReader(

     "select T.title, T.type from Titles T " +

     " inner join titleauthor TA on T.title_id = TA.title_id " +

     " inner join authors A on A.au_id = TA.au_id " +

     " where TA.au_id = '" + authorID + "'");

 }

}

Figure 2: Implementation of the Authors class.

 

As you can see from the example in Figure 2, the Authors class has three methods: GetSqlDataReader, GetAuthors, and GetTitlesByAuthors. GetAuthors simply returns all the authors from the authors table in the pubs database and GetTitlesByAuthors returns all the titles for a specific author based on the supplied author id. The implementation of both these methods is very similar, except for the difference in the query that is executed in these methods. Let s examine in detail the code of the GetSqlDataReader method.

 

To start, retrieve the connection string from the web.config file using the following code:

 

string connString = ConfigurationManager.

 ConnectionStrings["pubs"].ConnectionString;

 

For the above code to work, you must ensure that the connection string identified by the unique identifier pubs is stored in the web.config file directly under the element:

 

 

 

After you have the connection string, open the connection to the database using the SqlConnection object:

 

SqlConnection sqlConn = new SqlConnection(connString);

sqlConn.Open();

 

Then create an instance of the SqlCommand object and set its properties to appropriate values:

 

SqlCommand sqlCmd = sqlConn.CreateCommand();

sqlCmd.CommandText = sql;

 

Finally, execute the query by calling the ExecuteReader method of the SqlCommand object and return the SqlDataReader object back to the caller:

 

SqlDataReader reader = sqlCmd.ExecuteReader();

return reader;

 

Now that you have an understanding of the methods required for retrieving the data, let s turn our focus to the ASP.NET page that consumes these methods.

 

Creating the ASP.NET Page that Consumes the Class

Figure 3 shows an ASP.NET page named Authors.aspx that implements master-details capabilities by taking advantage of the ObjectDataSource control. Through the attributes of the ObjectDataSource control, the page utilizes the methods of the Authors class.

 

<%@ Page Language="C#" %>

 Authors Page

 

   

     id="authorsSource" typename="Authors"

     selectmethod="GetAuthors">

   

   

     id="titleauthorsSource" typename="Authors"

      selectmethod="GetTitlesByAuthors">

     

       

         name="authorID" controlid="ddlAuthors"

         defaultvalue="" propertyname="SelectedValue">

       

     

   

   Select Authors:

   

     datavaluefield="au_id" autopostback="true"

     id="ddlAuthors" datasourceid="authorsSource"

     runat="server" width="192px">

   

   

   

     datasourceid="titleauthorsSource">

     

     

   

 

Figure 3: Declaratively consuming middle-tier objects.

 

Let s walk through the code shown in Figure 3; it starts by declaring an ObjectDataSource named authorsSource. But before looking at the code, let s understand the two important attributes of the ObjectDataSource control. The TypeName attribute allows you to specify the name of the class to which you want to bind this control. The SelectMethod attribute allows you to specify the name of the method to invoke in the class. You use these methods to specify the name of the class and its method to which to bind the ObjectDataSource control. For authorsSource, set these attributes to Authors and GetAuthors.

 

Then bind the data in this authorsSource control to a DropDownList control named ddlAuthors by setting the DataSourceID attribute of the DropDownList to authorsSource. After that, declare one more ObjectDataSource control named titleauthorsSource. Basically, this control will be directly bound to the output of the GetTitlesByAuthors method. As previously noted, the GetTitlesByAuthors method takes an author id as an argument and returns all the titles of a specific author. To be able to invoke this method, the authorsSource control should be able to pass in the selected author id from the DropDownList. You specify the value for the SQL query parameter using the SelectParameters template. In this case, you want to retrieve the value of the author id using the SelectedValue property of the DropDownList. To do this, set the ControlID attribute of the ControlParameter template to the name of the DropDownList and the PropertyName attribute to SelectedValue. This allows the author id selected in the authors dropdownlist to be used as an argument to the SQL query. You also set the default value of "" for the author id using the DefaultValue property. This default value will be used when the page is requested the first time.

 

In addition to the ControlParameter template, you can also use any one of the following parameter objects to provide values for the parameterized query:

  • QueryStringParameter. Using this template, you can get the value of the parameter from a key-value combination in the current query string.
  • SessionParameter. Allows you to get the parameter value from a specified Session variable.
  • CookieParameter. Allows you to get the parameter value from a specified cookie.
  • FormParameter. Allows you to get the parameter value from a control on the page.
  • ProfileParameter. Allows you to get the parameter value from a property stored in the Profile object.

 

As you can see, you have accomplished all of these declaratively without writing even a single line of code. If you execute the code from Figure 3 by navigating to the page using the browser, you ll see an output as shown in Figure 4.

 


Figure 4: Output of the Authors.aspx page.

 

When you change the authors from the dropdownlist in Figure 4, the GridView will be refreshed to display the appropriate titles for a specific author.

 

Binding Generic Collections to an ObjectDataSource Control

In this section, you ll see how to return a generic collection from a middle-tier object and bind it directly to the ObjectDataSource control. The ObjectDataSource control is then bound to a DropDownList control so that the values returned through the collection can be displayed in the dropdownlist. To begin, create a class named Author that acts as the placeholder for capturing attributes related to an author (the code for the Author class is shown in Figure 5).

 

public class Author

{

 private string _authorID;

 private string _authorName;

 public string AuthorID

 {

   get

   {

     return _authorID;

   }

   set

   {

     _authorID = value;

   }

 }

 public string AuthorName

 {

   get

   {

     return _authorName;

   }

   set

   {

     _authorName = value;

   }

 }

}

Figure 5: The Author class.

 

Implementing the Author class is very simple and straightforward: It has only two properties, named AuthorID and AuthorName. Now that the Author class is created, let s look at the code of the method that returns a generic collection of type Author. To this end, add to the previously created Authors class a method named GetAuthorsAsCollection (see Figure 6).

 

public IList GetAuthorsAsCollection()

{

 IList authorColl = new List();

 // Create the SqlDataReader object and return it

 using (SqlDataReader reader = GetSqlDataReader(

       "Select au_id, au_lname + ' ' +

       au_fname as Name from authors"))

 {

   while (reader.Read())

   {

     Author authorObj = new Author();

     authorObj.AuthorID = reader["au_id"].ToString();

     authorObj.AuthorName = reader["Name"].ToString();

     authorColl.Add(authorObj);

   }

 }

 return authorColl;

}

Figure 6: Returning generic collections from the middle-tier object.

 

In the code shown in Figure 6, you start by declaring an object of type IList generic collection and assign that to the generic collection of type List. After you have the results in a SqlDataReader object, you loop through the SqlDataReader object, retrieve its values, and assign that to an Author object. After that, you add the Author object to the previously declared collection. After adding to the collection all the rows in the SqlDataReader object, you finally return the collection object back to the caller.

 

Now that you have the Authors object ready for consumption, the next step is to create the page that leverages the methods of the object. Figure 7 shows an ASP.NET page named GenericExampleAuthors.aspx that utilizes the GetAuthorsAsCollection method of the Authors class.

 

<%@ Page Language="C#" %>

 Authors Page

 

   

     

       id="authorsSource" typename="Authors"

       selectmethod="GetAuthorsAsCollection">

      

     Select Authors:

     

       datavaluefield="AuthorID" autopostback="true"

       id="ddlAuthors" datasourceid="authorsSource"

       runat="server" width="192px">

     

     

   

 

Figure 7: Use of ObjectDataSource to bind to a generic collection object.

 

Similar to the Authors.aspx page, the page example in Figure 7 also has an ObjectDataSource control declared, and the TypeName and SelectMethod attributes are set to Authors and GetAuthorsAsCollection, respectively. Then a DropDownList named ddlAuthors is bound to the ObjectDataSource through the DataSourceID attribute. Note that the DataTextField and DataValueField attributes are set to AuthorName and AuthorID, respectively. AuthorID and AuthorName are properties declared in the Author class and the output of those properties are directly displayed through the DropDownList control.

 

Conclusion

This article provides a thorough discussion of the concepts of object data binding in ASP.NET 2.0. This article also provides an example of how to utilize this new feature to facilitate the consumption of middle-tier objects from an ASP.NET page. Finally, you should now also have a better understanding of how to take advantage of the Generics concept for returning a collection object from the middle tier, which can then be directly bound to an ObjectDataSource control. Although the application we created was simple in functionality, it should provide a solid foundation for understanding how to use the features of the ObjectDataSource control to create true enterprise-class Web applications.

 

The sample code in this article is available for download.

 

Thiru Thangarathinam works at Intel Corp. in Chandler, AZ. He specializes in architecting, designing, and developing distributed enterprise-class applications using .NET-related technologies. Thiru has co-authored a number of books covering .NET-related technologies, and has been a frequent contributor to leading technology-related online publications. He can be reached at mailto:[email protected].

 

App_Code Directory

The App_Code directory, like the bin directory, is a special directory used by ASP.NET, but with the following exceptions. While the \bin directory is designed for storing pre-compiled assemblies used by your application, the App_Code directory is designed for storing class files to be compiled dynamically at run time. This allows you to store classes for business logic components, data access components, and so on, in a single location in your application, and use them from any page.

 

Because the classes are compiled dynamically at run time and automatically referenced by the application containing the \App_Code directory, you don t need to build the project before deploying it, nor do you need to explicitly add a reference to the class. ASP.NET monitors the App_Code directory and when new components are added, it dynamically compiles them. This makes it possible for you to easily make changes to a component and deploy with a simple XCOPY or with a drag-and-drop operation.

 

In addition to simplifying the deployment and referencing of components, the \App_Code directory also simplifies the creation and accessing of resource files (.resx) used in localization, as well as automatically generating and compiling proxy classes for WSDL files (.wsdl).

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish