Bind Web Controls to a Custom Class

Well- designed applications rigorously separate their data access logic from the rest of their code. In ASP.NET 2.0, you can achieve this separation while still using the new ASP.NET data source controls for convenient no-code-required design-time data binding. The secret is to use the new ObjectDataSource control, which knows how to fetch results from a data access class. You can then bind other controls to the ObjectDataSource for quick and easy web page display.

Note

Want to use data source binding without scattering database details throughout dozens of web pages? The ObjectDataSource control provides the solution.

How do I do that?

To use the ObjectDataSource control, you must first create a custom class that retrieves the data from the database. The database class will contain one method for every database operation you want to perform. Methods that retrieve results from the database can return DataTable or DataSet objects, collections, or custom classes.

Example 4-1 shows a database class called CustomerDB that provides a single GetCustomers( ) method. The GetCustomers( ) method queries the database and returns a collection of CustomerDetails objects. The CustomerDetails object is also a custom object. It simply wraps all the details of a customer record from the database.

Example 4-1. A custom database class

Imports System.Data.SqlClient
Imports System.Collections.Generic
    
Public Class CustomerDB
    
    Private ConnectionString As String = _
    "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=SSPI"
    
    Public Function GetCustomers( ) As List(Of CustomerDetails)
        Dim Sql As String = "SELECT * FROM Customers"
    
        Dim con As New SqlConnection(ConnectionString)
        Dim cmd As New SqlCommand(Sql, con)
        Dim Reader As SqlDataReader
        Dim Customers As New List(Of CustomerDetails)
        Try
            con.Open( )
            Reader = cmd.ExecuteReader( )
            Do While Reader.Read( )
                Dim Customer As New CustomerDetails( )
                Customer.ID = Reader("CustomerID")
                Customer.Name = Reader("ContactName")
                Customers.Add(Customer)
            Loop
        Catch Err As Exception
            Throw New ApplicationException( _
             "Exception encountered when executing command.", Err)
        Finally
            con.Close( )
        End Try
    
        Return Customers
    End Function
    
End Class
    
Public Class CustomerDetails
    
    Private _ID As String
    Private _Name As String
    
    Public Property ID( ) As String
        Get
            Return _ID
        End Get
        Set(ByVal Value As String)
            _ID = Value
        End Set
    End Property
    
    Public Property Name( ) As String
        Get
            Return _Name
        End Get
        Set(ByVal Value As String)
            _Name = Value
        End Set
    End Property
    
End Class

There are a couple of important points to note about this example. First, the database class must be stateless to work correctly. If you need any information, retrieve it from the custom application settings in the web.config file. Second, notice how the CustomerDetails class uses property procedures instead of public member variables. If you use public member variables, the ObjectDataSource won't be able to extract the information from the class and bind to it.

Tip

Example 4-1 uses a generic collection. For more information on this new CLR feature, refer to the lab Section 2.5 in Chapter 2.

To use the custom data access class in a data-binding scenario, you first need to make it a part of your web application. You have two options:

  • Place it in a separate class library project and then compile it to a DLL file. Then, in the web application, add a reference to this assembly. Visual Studio will copy the DLL file into the Bin subdirectory of your web application.

  • Put the source code in an ordinary .vb file in the App_Code subdirectory of your web application. ASP.NET automatically compiles any source code that's in this directory and makes it available to your web application. (To make sure it's compiled, choose Build → Build Website before going any further.)

Once you've taken one of these steps, drag an ObjectDataSource from the data tab of the Visual Studio toolbox onto the design surface of a web page. Click the control's smart tag and choose Configure Data Source. A wizard will appear that lets you choose your class from a drop-down list (a step that sets the TypeName property) and asks which method you want to call when performing a query (which sets the MethodName property).

Here's what the completed ObjectDataSource control tag looks like in the .aspx page of this example:

<asp:ObjectDataSource ID="ObjectDataSource1" Runat="server"
  TypeName="CustomerDB" SelectMethod="GetCustomers">
</asp:ObjectDataSource>

You are now able to bind other controls to the properties of the CustomerDetails class. For example, this BulletedList exposes the CustomerDetails.Name information for each object in the collection:

<asp:BulletedList ID="BulletedList1" Runat="server"
  DataTextField="Name" DataSourceID="ObjectDataSource1">
</asp:BulletedList>

When you run the application, the BulletedList requests data from the ObjectDataSource. The ObjectDataSource creates an instance of the CustomerDB class, calls GetCustomers( ), and returns the data.

What about...

...updating a database through an ObjectDataSource? Not a problem. Both the ObjectDataSource and the SqlDataSource controls discussed in the previous lab, "Bind to Data Without Writing Code" support inserting, updating, and deleting records. With SqlDataSource, you simply need to set properties such as DeleteCommand, InsertCommand, and UpdateCommand with the appropriate SQL. With the ObjectDataSource, you set properties such as DeleteMethod, InsertMethod, and UpdateMethod by specifying the corresponding method names in your custom data access class. In many cases, you'll also need to specify additional information using parameters, which might map to other controls, query string arguments, or session information. For example, you might want to delete the currently selected record, or update a record based on values in a set of text boxes. To accomplish this, you need to add parameters, as described in the previous lab "Bind to Data Without Writing Code."

Once you've configured these operations (either by hand or by using the convenient design-time wizards), you can trigger them by calling the Delete( ), Insert( ), and Update( ) methods. Other controls that plug in to the data source control framework can also make use of these methods. For example, if you configure a SqlDataSource object with the information it needs to update records, you can enable GridView editing without needing to add a line of code. You'll see an example of this technique with the DetailsView control in the upcoming lab "Display Records One at a Time."

Where can I learn more?

For more information, look up the index entry "data source controls" in the MSDN help library. To learn about the new GridView, refer to the next lab, "Display Interactive Tables Without Writing Code."

Get Visual Basic 2005: A Developer's Notebook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.