There exists a wide variety of ways in which data for a web page can be retrieved from a data store. One of the ways introduced in ASP.NET 2.0 involves using the ObjectDataSource control. This article discusses the ObjectDataSource control and how it fits into the ASP.NET 2.0 toolkit. A working example is provided demonstrating how the ObjectDataSource control can be used with a typed data set to provide search results to a GridView that are filtered based upon search parameters entered into other controls on the same page. The results can be paged and sorted within the grid, demonstrating some of the additional capabilities that the ObjectDataSource control provides.
What is it?
In high level terms, the ObjectDataSource is described as “…a middle-tier object with data retrieval and update capabilities” and “…acts as a data interface for data-bound controls“. Fancy! What does this really mean? In basic terms, it can be thought of as wrapping up the code necessary to open a connection to a data store, execute a query and return a result set, as well as provide caching, paging, and parameter support.
The ObjectDataSource can be configured to retrieve some data so that other controls don’t have to worry about data store access. The benefits of this approach over having the controls on the page source the data from a database themselves is that it provides a single structured location to define the data retrieval operation and isolates that retrieval, ostensibly making maintenance and extensions to the page more robust and reliable. As a further benefit, being a web server control means that many uses require no compiled code-behind implementation and the configuration of the ObjectDataSource on the page can be changed in an .aspx page directly; eliminating the requirement for recompilation during maintenance.
For those wishing to follow along with additional reference information, the full declarative syntax for the ObjectDataSource control can be found here: http://msdn2.microsoft.com/en-us/library/ms227436.aspx.
For the purposes of this discussion, a simpler implementation path will be taken; the typed data-set. Strongly typed data sets were introduced in the .NET 1.0 framework and have been vastly enhanced in the .NET 2.0 framework. I would strongly advise anyone who wrote off .NET 1.0 typed data sets as over-bloated and under-implemented sledgehammers to take a look at the .NET 2.0 typed data set before passing judgment. For ease and efficiency of development and maintenance with little to no performance impact at run-time, typed data sets and the ObjectDataSource control can form one of the most powerful duos in any ASP.NET 2.0 developer’s toolkit. http://msdn2.microsoft.com/en-us/library/ms228150.aspx
The basic syntax to declare an ObjectDataSource on an ASPX page looks like the following:
<asp:ObjectDataSource ID=”srcSearchResults” runat=”server” SelectMethod=”GetData” TypeName=”VideoManagerTableAdapters.VideoTableAdapter”>
<asp:ControlParameter ControlID=”ddlGenre” Name=”Genre” PropertyName=”SelectedValue” Type=”String” />
There are a few interesting points to note about this basic declaration. First, the TypeName attribute, which identifies a class used to perform the actual database access operations. This gives the first clue as to how the ObjectDataSource control is performing its work. The second interesting point is the SelectMethod attribute, which specifies a method on that class that will be used to perform a select query. This gives the next clue as to how the pattern will work. When a control using the ObjectDataSource is bound, the method specified in the SelectMethod attribute will be invoked on an instance of the class specified in the TypeName attribute. The results of this query will then be used by the control that is binding data.
This raises an important question about how the class specified in the TypeName attribute of an ObjectDataSource is defined. Any object that satisfies the requirements of the ObjectDataSource can be specified in this attribute. For more information on the specifics of those requirements and for instructions on how to implement a custom sourcing object, see this article:
What about parameters?
When executing a query to return a result set from a data store, it is often desirable to provide parameters to the query in order to narrow the results that are returned. Imagine a search page on a video library web site that allows a user to specify a genre, director, and title as possible search parameters. When executing the query to return the list of results, any user input provided for those three attributes would need to be passed as well. The ObjectDataSource provides such a mechanism for supplying parameters to queries. Additionally, the ObjectDataSource allows for a different set of parameters to be provided for each of the types of queries configured across it, but more on this later. The syntax used to supply parameters should be instantly familiar to developers who have worked up through the various releases of ADODB, including the popular ADODB 2.5 used with VB6 and the even more popular ADODB.NET released with the .NET 1.0 framework.
The ObjectDataSource control recognizes seven parameter types. Each of these can be provided to any of the five query types. The following tables list the query and parameter types along with a brief description of each.
|SelectParameters||The collection of parameters to supply to the SELECT query.|
|InsertParameters||The collection of parameters to supply to the INSERT query.|
|UpdateParameters||The collection of parameters to supply to the UPDATE query.|
|DeleteParameters||The collection of parameters to supply to the DELETE query.|
|FilterParameters||The collection of parameters to supply for the Filter expression.|
|Parameter Type Name||Description|
|ControlParameter||A parameter sourced from another ASP.NET web server control.|
|CookieParameter||A value sourced from a cookie.|
|FormParameter||An item of form-post data received from an HTTP post.|
|Parameter||A literal parameter with either a hard-coded value or sourced programmatically.|
|ProfileParameter||Sourcing a parameter from the current security profile.|
|QueryStringParameter||A parameter sourced from a query-string value.|
|SessionParameter||A value read from the session object.|
What else can it do?
In a subsequent article, I am going to discuss the additional features and potential pitfalls of the ObjectDataSource control. These include paging, filtering, and sorting, how caching can work, and the list of most common traps and errors that you might encounter while using the control. For now, it is worthwhile playing with the ObjectDataSource control on a few test pages, examining its syntax and thinking about its application as a middle-tier enabling layer. In essence that is what the ObjectDataSource is trying to provide, a managed ability to employ a middle-tier in your solution architecture that manages some of the grey area items between those layers such as connection string management, parameter marshalling, and the provision of a single point of reference for user interface layer controls.
The following section contains a full working example using an ObjectDataSource and a typed data set to bind search results to a GridView on an .aspx page. The ObjectDataSource takes parameters from other controls on the page to provide filtering capabilities to the search.
Creating the SQL database
Open SQL Management Studio and connect to a SQL database server. Create a new database by right-clicking over the Databases folder and selecting New Database… Enter the name ObjectDataSourceDemo as the name of the database and click OK. Expand the new database in the object explorer window and add a new table to the database by right-clicking the Tables folder and selecting New Table… Fill out the table definition as shown below being sure to set VideoID as the Primary Key and the Identity Specification (Is Identity) to Yes. Press Ctrl-S to save the table, which will display the Choose Name dialog. Enter Video as the name of the table and click OK.
Open the table by expanding the Tables folder in the object explorer and then right-clicking over the Video table in the list and selecting Open Table. Enter a few rows of data in the table and then close SQL management studio. Remember that VideoID is an identity column and does not need to have data typed into it. An ID will be assigned automatically by navigating to the next row.
NOTE: In a real solution, the data for directors and genre would not be stored directly as strings within the Video table. For the simplicity and brevity of this example, the contents of several logical tables have been compressed into a single table.
Defining a Typed Data Set
In Visual Studio, create a new C# web site in a new solution. To add a typed data set, right-click the project in the solution explorer and select Add->New Item to show the Add New Item dialog. Select DataSet from the list of item types, enter a name, and then click the Add button.
This will open the newly added data set in design mode. From here you can add items to the data set and visually build its definition. For the purposes of this article, we’re going to add a TableAdapter to the data set for use in an ObjectDataSource. For more information on typed data sets and table adapters, see this article: http://aspnet.4guysfromrolla.com/articles/020806-1.aspx
First, right-click over the design pane and select Add -> TableAdapter. This will add a table adapter to the data set and open the TableAdapter Configuration Wizard. Create a new database connection to the SQL server and select the ObjectDataSourceDemo as the database to connect to.
Click OK on the Add Connection dialog and then click Next to save the connection string to a configuration file. For this example we will just use SQL statements to connect to the database. Select the radio button marked Use SQL statements and click Next. Type the following SQL into the dialog box and click Next.
SELECT Title, [Director Name], Genre
WHERE Genre = @Genre
Finally, accept the default names for the Fill and Return actions of the TableAdapter and click Next. Click Finish to close the dialog. The new table adapter will be displayed in the design pane and you can now save the dataset.
(The newly created TableAdapter)
Creating the ASPX page
In the solution explorer pane, open the Default.aspx page that was added when the web site project was created. Add the following code between the <form> tags on the page:
<asp:DropDownList ID=”ddlGenre” runat=”server” AutoPostBack=”true”>
<asp:ListItem Text=”Action” Value=”Action” />
<asp:ListItem Text=”Comedy” Value=”Comedy” />
<asp:ListItem Text=”Mystery” Value=”Mystery” />
<asp:GridView ID=”gvSearchResults” runat=”server”
<asp:BoundField DataField=”Title” HeaderText=”Video Title” />
<asp:BoundField DataField=”Director Name” HeaderText=”Director Name” /> <asp:BoundField DataField=”Genre” HeaderText=”Genre” />
<asp:ObjectDataSource ID=”srcSearchResults” runat=”server”
<asp:ControlParameter ControlID=”ddlGenre” Name=”Genre”
PropertyName=”SelectedValue” Type=”String” />
Running the Sample
While not the most advanced example out there, this demonstrates the use of an ObjectDataSource control as a data source proxy for another ASP.NET web control. The DropDownList control is set to post the page back when the selected item in the list is changed. Upon this post-back, the GridView control is data-bound. It is during this data-binding step that the data source specified for the GridView, in this case our ObjectDataSource control, performs its work and retrieves the search results from the database. It uses the selected value of the genre DropDownList control as a parameter to supply during the search.