4.4. 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.
4.4.1. 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:
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 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 Runat="server" DataTextField="Name" DataSource> </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.
4.4.2. 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."
4.4.3. 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."