Programming the ObjectDataSource Control

Discover Some Advanced Features of the ObjectDataSource ASP.NET Control

Dino Esposito

October 30, 2009

10 Min Read
ITPro Today logo in a gray background | ITPro Today

The ObjectDataSource control enables developers toassociate data or business layer classes with the ASP.NET data bindingmechanism. I covered some aspects of the ObjectDataSource control in "Cache In Using the ObjectDataSource Control" specifically, the object instantiation and data caching. Methods of such classes can be designated as methods for data-boundcontrols to execute common operations, such as select, delete, update, andinsert. Like other data source controls, ObjectDataSource supports declarativeparameters to allow developers to pass page-level variables to the object smethods.

The ObjectDataSource control is not the panacea of all Webdata access issues. It is simply a tool; a powerful tool indeed but notnecessarily ideal for every situation. The ObjectDataSource control isparticularly suited for declarative programming and, in general, all thosescenarios where your information fits well in the control s programminginterface. A slogan I usually apply to the ObjectDataSource control is, eithereasy or nothing. The ObjectDataSource control wraps a good deal of internaltasks, and its overall performance is slightly worse than classic binding. Soyou might be happy to pay extra for quicker programming; but would you pay moreto get less?

In this article, I ll go throughother programming aspects, such as paging, sorting, and conflict detectionduring updates. To start, though, I ll discuss parameter binding.

 

Parameter Binding

The primary goal of the ObjectDataSource control is to create,read, update, delete (CRUD). The methods on the objectshould map closely to the semantics of CRUD. If your business layer doesn tallow for this, you re better off wrapping your business layer into anintermediate object that adapts the native interface to the requirements ofObjectDataSource. If this sounds like it s costly or impossible, then simplydrop ObjectDataSource and resort to classic binding.

Methods bound to properties like SelectMethod,DeleteMethod, InsertMethod, and UpdateMethod can accept any number ofparameters. You use ad hoccollections such as SelectParameters, DeleteParameters, InsertParameters, andUpdateParameters to pass parameters to methods. These collections are persistedto the ASPX source file and bind live data to a method s formal parameters in adeclarative manner. You declare the source of the parameter data and how itbinds to a given formal parameter on the method s signature. Figure 1 lists allsupported parameter sources.

Parameter

Description

ControlParameter

Gets the parameter value from any public property of the specified server control.

CookieParameter

Gets the parameter value from the content of the specified HTTP cookie property.

FormParameter

Gets the parameter value from the specified input field in the HTTP request form.

Parameter

Gets the parameter value from the specified constant value.

ProfileParameter

Gets the parameter value from the specified property name in the profile object created from the application s personalization scheme.

QueryStringParameter

Gets the parameter value from the specified variable in the request query string.

SessionParameter

Gets the parameter value based on the content of the specified session state slot.

Figure 1: Parametertypes in ASP.NET 2.0.

Each parameter class has a Name property and a set ofproperties specific to its role and implementation. To understand declarativeparameters in data source controls, take a look at the following code snippet:

      

The bound object data source contains a method named Load,which takes a single string parameter named id. The data source controlautomatically invokes the Load method passing the information returned by theControlParameter object. The value of the parameter is determined by the valueof the Text property on the CustomerID control (likely a TextBox). The ID ofthe control is in the ControlId attribute. You get an exception if the pagethat hosts the preceding code lacks a control with the specified ID and apublic property named Text.

Read operations normally don t require many parameters,and are relatively easy to handle; but what about write operations? To delete arecord, you likely need just the unique ID. However, to add or update a recordyou must pass all required values. Depending on the structure of the record,this can be quite a few values. There s a better approach than simplyenumerating a potentially long list of parameter values. You can design yourbusiness layer according to the Data Mapper pattern and reason in terms ofclasses and entities then mapped to tables. In other words, if you re going tocreate a manager for customer entities, you end up having methods such as thoseshown here:

public class CustomerManager{  public void Save(Customer c) { ... }  public void Insert(Customer c) { ... }  public void Delete(Customer c) { ... }}

The Customer class is an entity class that represents yourdefinition of a customer. Internally, the methods will fall into some rawADO.NET code to run database commands, as appropriate. How can you tell theObjectDataSource about this entity class? You use the DataObjectTypeNameproperty:

Note that when you set the DataObjectTypeName property,any parameters collection for update, insert, and delete operations is ignored.The ObjectDataSource instantiates a default instance of the data object typebefore the write operation is performed. Next, it attempts to fill the publicmembers of the data object type with the values of any matching input fieldsfound around the data-bound control (say, the GridView) associated with theObjectDataSource. Because this work is performed using reflection, the names ofthe input fields in the data-bound control must match the names of publicproperties exposed by the object in the DataObjectTypeName property. As aresult, you can t use complex data types to define the Customer class:

public class Customer {  public string CompanyName { ... }  public string ContactName { ... }  public Address OfficeAddress { ... }}

The CompanyName and ContactName members have good chancesto match an input field in the bound control because they represent individualvalues. The same can t be said for the OfficeAddress member, which is declaredof a custom type like Address. If you go with this schema, all the members inAddress will be ignored and any related information won t be carried into theSave method. Instead, all the members in the Address data structure shouldbecome members of the Customer class.

When it comes to setting parameters, you can also rely onthe Updating, Deleting, and Inserting events fired by the ObjectDataSourcecontrol. When using ObjectDataSource with an ASP.NET 2.0 made-to-measurecontrol (i.e., GridView), most often the binding is totally automatic and you reapparently kept off the business. If, for whatever reasons, theObjectDataSource control doesn t load all the data its method needs to performthe operation, in the Updating (or similar) events, you kick in and completethe list of input parameters for the method:

protected void Updating(object sender,   ObjectDataSourceMethodEventArgs e){   Customer cust = (Customer) e.InputParameters[0];   cust.CustomerID = "...";}

Where should you normalize input params and assign defaultvalues? Parameters can be given default values both declaratively andprogrammatically through the Updating, Deleting, and Inserting events. Thebest, though, is that you set the DefaultValue property of the parameter tonull and deal with unspecified parameters in the business or data access layer.

 

Conflict Detection

In a situation in which multiple users have read/writeaccess to the database, what should be the behavior of the update/deletemethods if the record they attempt to work on has been modified?

The ObjectDataSource control uses the ConflictDetectionproperty to determine what to do when performing update and delete operations.The property is declared of type ConflictOptions (an enum type). The defaultvalue is OverwriteChanges, which means that any operation happens regardless ofwhether values in the row have changed since they were last read. This approachis also known as last-win. Alternatively, you can use the CompareAllValuesoption. In this case, the ObjectDataSource control passes itsupdate and delete methods as well as the original data read from thedatabase. As you can see, though, changing the value of ConflictDetection isnot enough. Your data access layer must be written to handle conflictsproperly. In other words, the ConflictDetection property simply indicates howmany parameters are passed to the methods. But still, the data access layer isin charge of detecting and handling conflicts by using proper SQL code.Finally, note that if DataObjectTypeName is used, Update and Delete methodsmust take two parameters for old and new values, respectively.

 

Paging and Sorting

The ObjectDataSource control provides an infrastructurefor paging and sorting; but actually, any such operations should be implementedin the data access layer in the class bound to ObjectDataSource.

Let s consider paging first. Three properties participatein paging: EnablePaging, StartRowIndexParameterName, andMaximumRowsParameterName. EnablePaging is a Boolean property that enables anddisables paging. The default value is false, meaning that paging is not turnedon automatically. The property StartRowIndexParameterName indicates the name ofthe formal parameter in the Select method that accepts the value for the firstrecord to retrieve. Likewise, the property MaximumRowsParameterName sets thename of the formal parameter in the Select method that accepts the value forthe maximum number of records to retrieve. Figure 2 shows the details. It isassumed that the Select method has overloads that support paging and sorting.How paging and sorting are implemented in the data access layer is up to theprogrammer.

         

Figure 2: Pagingand sorting in ObjectDataSource.

Sorting capabilities of the ObjectDataSource pass throughthe SortParameterName property. As usual, the property indicates the name ofthe formal parameter in the Select method that accepts the value for the fieldto sort by.

How does the ObjectDataSource control use the paging andsorting information? What s the purpose of passing the name of formalparameters? Commonly, the ObjectDataSource receives the input for paging orsorting its data from a bound control; for example, a GridView. The GridViewwill also pass the index of the first record to retrieve and the size of thepage; for sorting, the GridView will pass the sorting expression. Internally,the ObjectDataSource uses reflection to prepare the call to its data sourceobject. In doing so, it needs to know which parameters in the method sprototype are to be bound to paging and sorting information.

 

Conclusion

Data source controls such as SqlDataSource andObjectDataSource are simply programming tools and should be used only if they reright for the job you re trying to accomplish. From a functional perspective, classicbinding and data source controls are nearly identical. Classic binding providesa slightly better performance as it uses no reflection but requires you towrite more code. Should you opt for SqlDataSource or ObjectDataSource?SqlDataSource is designed for use in two-tier applications where the userinterface layer communicates directly with the data tier. In contrast,ObjectDataSource is ideal for three-tier scenarios where you connect the userinterface to the middle tier. ObjectDataSource supports advanced features, suchas caching, paging, and sorting as long as these features are supported inthe middle tier. As a result, with ObjectDataSource you must have a strong andwell designed business layer. That s the key point. First, you make up yourbusiness layer and then you adapt itto work with ObjectDataSource, creating a wrapper object if this is the case.It doesn t work the other way around.

 

Dino Esposito is aSolid Quality Learning mentor and author of IntroducingASP.NET 2.0 AJAX Extensions and ProgrammingMicrosoft ASP.NET 2.0-Core Reference, both from Microsoft Press. Basedin Italy, Dinois a frequent speaker at industry events worldwide. Join the blog at http://weblogs.asp.net/despos.

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like