Size Matters

Minimize Code with the ObjectDataSource Control

CoverStory

LANGUAGES: C# | VB.NET

ASP.NET VERSIONS: 2.0

 

Size Matters

Minimize Code with the ObjectDataSource Control

 

By Dan Wahlin

 

With the release of .NET version 2, Web application development has become more productive than ever especially when it comes to building highly scalable, data-driven Web applications. Many new server controls and framework classes added into version 2 of the framework make the process of generating dynamic Web pages less code-intensive and much simpler. Why does that matter? It s really very simple: less code leads to fewer bugs, easier maintenance, and greater overall productivity.

 

In addition to all the fantastic ASP.NET server controls being released in version 2 of the framework, there are also five new data source controls. These controls include SqlDataSource, XmlDataSource, AccessDataSource, SiteMapDataSource, and ObjectDataSource. By using data source controls in your ASP.NET Web Forms you can significantly minimize the amount of code needed to gather data and bind it to server controls, such as the new GridView or DetailsView controls. In this article I ll focus on the ObjectDataSource control and demonstrate how it can be used to tie presentation code to business layer code with a minimal amount of effort.

 

Why Use the ObjectDataSource Control?

I m a big fan of the n-tier architecture model, where presentation, business, and data layers are separated into logical tiers for greater code re-use and more flexibility when it comes to future code changes (see Figure 1). With the release of the ObjectDataSource control, hooking the presentation tier to the business tier is easier than ever and in many cases can be done without writing a single line of code.

 


Figure 1: An n-tier architecture model provides for better code re-use and helps isolate the presentation tier from other tiers, such as the data tier. This provides for a more loosely coupled system.

 

The ObjectDataSource control can be utilized by dragging and dropping it from the Visual Studio.NET 2005 (or Visual Web Developer 2005) toolbox onto an ASP.NET Web Form. Those who prefer to enter code manually can enter into the source code editor code similar to this:

 

 SelectMethod="GetCustomers" TypeName="BAL"

 DataObjectTypeName="Customer"

/>

 

The ObjectDataSource data source control works by using reflection to load a specific object (BAL in the code shown above), and then call one or more of its member methods. While this may raise a red flag to some because reflection relies on late-bound operations, performance is quite good in the non-scientific tests I ve run. Obviously you ll want to test it within the context of your application to ensure that it meets performance expectations.

 

Selecting a business object that the ObjectDataSource control can utilize is most easily accomplished by using the built-in wizard available in the various 2005 development environments (see Figure 2). The wizard makes selecting objects and methods a snap and requires no code to be written. Methods can be chosen for select, insert, update, and delete operations.

 


Figure 2A: The ObjectDataSource control wizard allows objects and methods to be selected quickly and easily without writing code. This image shows how a business object can be selected.

 


Figure 2B: This image shows how methods within a business object can be used to perform various CRUD operations.

 

After a business object and associated methods have been assigned to the ObjectDataSource, it can be used as a data source for server controls such as the DropDownList, GridView, DetailsView, and others. The following code shows how a GridView control s DataSourceID property can be used to refer to an ObjectDataSource control named odsCustomers (the GridView control replaces the DataGrid control found in ASP.NET 1.1):

 

 DataSourceID="odsCustomers" />

 

By referencing the data source control, the GridView control will automatically be populated with any available data without writing additional code. Data binding was quite straightforward in .NET version 1.1, but you can see that it s even easier in version 2 even when data must be obtained from business or data tier code.

 

Creating Business and Data Tiers

Now that you ve seen some of the fundamentals of the ObjectDataSource control, let s see how it can be put to use to tie together different code tiers. First we ll need to write business and data tier classes that handle business rules and data access, respectively. Figure 3 shows a method named GetCustomers in a data tier class named DAL. This method calls a SQL Server stored procedure that returns as an array of Customer objects all customers in the Northwind database s Customers table. Each customer object is created and filled by calling another method named FillCustomer. The Customer object contains basic properties such as CustomerID, ContactName, City, and PostalCode, plus a few others.

 

public static Customer[] GetCustomers() {

 Customer[] custs = null;

 DbConnection conn = null;

 DbDataReader reader = null;

 try {

   conn = GetConnection("NorthwindConnStr");

   conn.Open();

   DbCommand cmd = conn.CreateCommand();

   cmd.CommandText = "GetCustomers";

   cmd.CommandType = CommandType.StoredProcedure;

   reader = cmd.ExecuteReader();

   custs = FillCustomer(reader);

 }

 catch (Exception exp) {

   HttpContext.Current.Trace.Warn("Error",

     "Error in GetCustomers: " + exp.Message);

   return null;

 }

 finally {

     if (conn != null) conn.Close();

     if (reader != null) reader.Close();

 }

 return custs;

}

private static DbConnection GetConnection(string connStrName) {

 ConnectionStringSettings s =

   ConfigurationManager.ConnectionStrings[connStrName];

 DbProviderFactory f =

   DbProviderFactories.GetFactory(s.ProviderName);

 DbConnection conn = f.CreateConnection();

 conn.ConnectionString = s.ConnectionString;

 return conn;

}

private static Customer[] FillCustomer(DbDataReader reader) {

 List custList = new List();

 while (reader.Read()) {

   Customer cust = new Customer();

   cust.Address = reader["Address"].ToString();

   cust.City = reader["City"].ToString();

   cust.CompanyName = reader["CompanyName"].ToString();

   cust.ContactName = reader["ContactName"].ToString();

   cust.ContactTitle = reader["ContactTitle"].ToString();

   cust.Country = reader["Country"].ToString();

   cust.CustomerID = reader["CustomerID"].ToString();

   cust.Fax = reader["Fax"].ToString();

   cust.Phone = reader["Phone"].ToString();

   cust.PostalCode = reader["PostalCode"].ToString();

   cust.Region = reader["Region"].ToString();

   custList.Add(cust);

 }

 return custList.ToArray();

}

Figure 3: The GetCustomers method handles all data access functionality and returns to the caller a resultset containing customer records. The GetCustomers method shown here is a member of a data tier class named DAL (data access layer).

 

Another method named GetConnection is also shown in Figure 3 to demonstrate using the new DbProviderFactory class found in .NET version 2. Although a complete discussion of this class and its related classes is beyond the scope of this article, in a nutshell, the DbProviderFactory class allows generic data access code to be written that isn t tied to a specific database vendor such as Microsoft or Oracle. In addition to using the DbProviderFactory class, the GetConnection method in Figure 3 also shows how to access the new settings within web.config using the ConfigurationManager class.

 

After the data access layer code is written, a business tier class is needed to call the GetCustomers method found within the data tier. Figure 4 shows a simple business tier method named GetCustomers that is a member of a class named BAL. Although quite simple, GetCustomers could include business rules required by the application, such as filtering or caching rules.

 

public static Customer[] GetCustomers() {

   return DAL.GetCustomers();

}

Figure 4: The GetCustomers method shown here is a member of the BAL class (business access layer) that handles business tier code execution.

 

Now that the business and data tier code has been written to select customers from the Northwind database, the ObjectDataSource can be combined with the new GridView server control to easily hook up the presentation tier to the business tier and display customers to end users. By mousing over the ObjectDataSource control while in design-mode in Visual Studio.NET 2005 (or Visual Web Developer 2005), the new smart tag functionality will appear as shown in Figure 5. By selecting Configure Data Source the BAL business class can be selected, as well as the GetCustomers method (refer back to Figure 2 for an example of the ObjectDataSource wizard).

 


Figure 5: The new smart tag functionality found in the 2005 developer tools allows easy access to an object s functionality. This example shows how to access the ObjectDataSource s wizard and select a business object and associated methods.

 

Updating, Deleting, and Inserting Records

To this point you ve seen how records can be selected using a tiered architecture and the ObjectDataSource control. However, nothing has been mentioned about performing insert, update, or delete operations. Fortunately, adding this functionality isn t too difficult. First, the appropriate methods must be added to the data and business tier classes. The sample code included with this article defines DeleteCustomer, UpdateCustomer, and InsertCustomer methods within each tier s class.

 

Performing update and delete operations is extremely easy using the GridView control along with the ObjectDataSource control. However, inserting records ended up requiring more code than I thought necessary, so I combined the GridView control with the DetailsView control because the DetailsView control is designed to handle update, delete, and insert operations directly.

 

If you re unfamiliar with the DetailsView control, it s used to display one record at a time and allows an end user to modify the record if desired. An example of using it to edit a record is shown in Figure 6.

 


Figure 6: Editing records in a database can be easily done by using the new DetailsView control. This example shows how to use the GridView control to allow users to select a specific record and then edit the record with the DetailsView control.

 

Because two controls are being used to display data (GridView and DetailsView), two ObjectDataSource controls are needed. The first selects all customer data and passes it to the GridView control for display. Once a user selects a record within the GridView, the second ObjectDataSource control grabs the proper customer data based on the CustomerID selected in the GridView and displays the customer data using the DetailsView control.

 

The second ObjectDataSource control also allows the selected record in the DetailsView control to be updated, deleted, or inserted by calling into the business tier class methods. These operations are made possible by using the ObjectDataSource wizard (again, refer to Figure 2) and require virtually no code to be written. In fact, by using only the GridView, DetailsView, and ObjectDataSource controls, a minimal amount of presentation tier code has to be written, which handles refreshing the GridView control as each record s data is changed. A portion of this code is shown below:

 

//Refresh GridView when DetailsView control (dvCustomer)

//insert event is fired so that new record displays.

protected void dvCustomer_ItemInserted(object sender,

 DetailsViewInsertedEventArgs e) {

   this.gvCustomers.DataBind();

}

 

Conclusion

Using the ObjectDataSource control will allow you to focus on the important parts of your application and not worry as much about hooking up the presentation and business tiers. This should lead to a reduction in development time, less bugs, and, ultimately, happier customers. The ObjectDataSource control certainly isn t perfect for every situation where an ASP.NET Web Form needs to consume business tier data; I ve run into several instances where I had to work outside the normal bounds of the control and write additional code to support it. However, when used appropriately, it can definitely jumpstart your ASP.NET 2.0 application development projects.

 

The sample code accompanying this article is available for download.

 

Dan Wahlin (Microsoft Most Valuable Professional for ASP.NET and XML Web services) is the president of Wahlin Consulting, as well as a .NET instructor at Interface Technical Training. Dan founded the XML for ASP.NET Developers Web site (http://www.XMLforASP.NET), which focuses on using XML, ADO.NET, and Web services in Microsoft s .NET platform. He s also on the INETA Speaker s Bureau and speaks to .NET User Groups around the US. Dan co-authored Professional Windows DNA (Wrox), ASP.NET: Tips, Tutorials, and Code (SAMS), and ASP.NET 1.1 Insider Solutions, and authored XML for ASP.NET Developers (SAMS).

 

 

 

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