Welcome to EMC Consulting Blogs Sign in | Join | Help

Simon Evans' Blog

My blog covers the technology areas I focus on here at EMC Consulting, namely Architecture using the .NET Framework, ASP.NET, WCF, WCF Data Services and Windows Azure Follow me on twitter @simonevans

Data binding to objects using the ObjectDataSource control in ASP.net 2.0

Introduction

If there’s one thing I like in life it’s a subject that brings out passionate love or hatred. Some examples include Marmite, The Smiths, and the work of Woody Allen. All of these examples I happen to love, but the best part about them all is that you never hear anyone say, “Yeah, The Smiths were ok”. Who wants to be just “ok”?

 

And so it is true with data binding. It is a subject that has sparked more debate in developer communities than any other I can think of – right back to the days of Visual Basic 5, when I first came across the concept.

 

People that love data binding love it because it saves an awful lot of effort in user interface coding. We developers often forget this point, because we are often guilty of wanting to create the most scalable, performing application – even if it is not truly required, will take us three times as much effort and will cost twice as much to maintain. A colleague of mine here at Conchango Howard van Rooijen sent me a link to nice blog by Brendan Tompkins on this subject.

 

I have generally fallen into the hate data binding camp when dealing with enterprise class web applications. I have always a problem with it from an architectural perspective; to gain the productivity benefits of data binding in previous versions of ASP.net, you really had to go down the Dataset road rather than an object orientated one, and using datasets to be seems like reverting back to a two tier application rather than fitting in with my nice n-tier architecture. Using Datasets steers you away from the benefits of an object orientated design, where my entity objects are passed into my business processes, nicely encapsulating my data. So what you benefited on the one hand with data binding, you had taken away with the other.

 

What I’ve always wanted was an easy to use method to bind to entities through my business tier using the Visual Studio designer. And now you can with the ObjectDataSource, so generally, I’m converted. And even better, we now easily do updates, inserts and deletes too.

Separating the view control from the data source

ASP.net 2.0 makes one very big conceptual difference to binding in ASP.net 1.1; there is separation between the control that the data is being bound to, and the control that is managing the data source. So we now have controls such as the GridView (a replacement for the DataGrid) and the DetailsView that support data being bound to them and we have controls such as the ObjectDataSource that manage where and how this data is made available to view. The GridView manages the visual rendering of data and the ObjectDataSource manages retrieving entities from my business tier.

Understanding the event driven model of object data binding

The main reason for using data binding is to save you code – a lot of code. In ASP.net 2.0, you can do simple data binding to retrieve objects with no code at all. This then leads to next question developers have, “Doesn’t that mean it’s inflexible”. Well, no, because the event model built in between the GridView and the ObjectDataSource is extremely flexible.

 

When selecting data in the GridView, the main binding events fire in the following order:

 

GridView

ObjectDataSource

Purpose

EventArgs

 

Selecting

Enables you to validate the parameters used to retrieve your object(s) before the object(s) are retrieved

ObjectDataSourceSelectingEventHandler

 

Selected

Enables you to examine an object retrieved from the data source by using the ReturnValue

ObjectDataSourceStatusEventHandler

RowCreated

 

Enables you to affect the row before the object has been bound to the fields

GridViewRowEventHandler

RowDataBound

 

Enables you to affect to row after the object has been bound, and evaluate the object that has been bound

GridViewRowEventHandler

 

 

 

 

 

 

When updating objects in the grid view the events fire in the following order:

 

GridView

ObjectDataSource

Purpose

EventArgs

RowCommand

 

Provides access to the command button that was clicked eg “Update”

GridViewCommandEventHandler

RowUpdating

 

Enables you to cancel an update before the update method on your business tier is called. Here you can handle changing mode in your GridView

GridViewUpdateEventHandler

 

Updating

Enables you to examine to contents of your object before performing the update and effect any of the parameters before they are passed into the method

ObjectDataSourceMethodEventHandler

 

Updated

Enables you to examine the return values from your update method

ObjectDataSourceStatusEventHandler

RowUpdated

 

Enables you to examine any exceptions throw by your update method and handle the GridView mode accordingly (eg stay in edit mode when the update has failed)

GridViewUpdatedEventHandler

 

Inserts and Deletes have equivalent events as updates, and the DetailsView control has events named “Item” rather than “Row” (e.g. ItemUpdating).

Using the events with your object model

The rich event model allows you to intercept the render of your view control at any point in the binding process. For selecting objects, the RowDataBound event is useful, because you can gain access to both the bound row and your object, which is useful for applying formatting to your row. The Selected event will gain you access to your object(s) as retrieved from your business tier.

 

For updating, the most useful event is RowUpdated. If your business tier manages validation errors by throw custom exceptions, you can use this event trap the custom exception, notify ASP.net that the exception has been handled, and then keep the control in edit mode:

 

  void CustomersGridView_RowUpdated(Object sender, GridViewUpdatedEventArgs e)

  {

   

    // Display whether the update operation succeeded.

    if(e.Exception == null)

    {

      Message.Text = "Row deleted successfully.";

    }

    else

    {

      Message.Text = "An error occurred while attempting to update the row.";

      e.ExceptionHandled = true;  

      e.KeepInEditMode = true;

    }

   

One final point on updates. Be sure to set DataKeys for all the data not being displayed on screen that you need to maintain the state for. Otherwise, this state data is lost when the data source calls the update method.

Designing entities for object data binding

There are a few limitations to object data binding. Your objects must have a default constructor. I have also had issues use objects of type IDictionary (although generic collections work very nicely ICollection). Also, if your objects nest other complex objects, you will have extra complexity binding to these.

Summary

Object data binding has converted me using data binding in ASP.net 2.0, because we now have all the benefits of code reduction in the presentation tier with losing the benefits of n-tier object orientated architecture.
Published Saturday, April 23, 2005 11:46 AM by simon.evans

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Khuzema said:

Dear Simon,

How we can use object data source with custom business object. What i
mean is any update,insert,delete is done on BO and then on final
submit,
i post it to database.

thanks & regards

Khuzema
khujema@yahoo.com
June 27, 2005 12:01 PM
 

simon.evans said:

What exactly do you mean by final submit? It sounds like you are suggesting you want to manage state of your business entites before you update them?

You should look at the ObjectDataSource as a control that calls methods from your business processes to Select, Insert, Update and Delete business entities (like CRUD operations).

With the exception of object properties put in the DataKeys collection, and the properties exposed for editing in a view control (such as GridView), the ObjectDataSource is stateless in nature.

If you have a scenario where you want to have multiple pages to edit your object data, with a single update at the end to update all the data, the object data source will only be used on the final update page, and you will need to use another mechanism for managing state for each page, such as Session or Profile.
June 29, 2005 1:59 PM
 

Khuzema said:

I am using issue tracker architecture and developed business object for my application. Now, in VS Beta 2, I humbly want to know how i can have same feature as dataset, in my Business object, what i mean is, if you have
dataset object and assign it to gridview, you can add/edit/delete row (without affecting table) and then post it back to database. Same thing i want to have for my business object (which is generic collection) assign to
gridview. So when I add records to my collection it should adds to mycollection, on delete it should deletes from the collection and on update it should updates my collection, then on final submit i loop through my
collection and do neccessary updates to my database (like a batch mode).

Why i need it:-
A) I have a child table which gets primary key from the Main table. So, if
my gridview source is Business Object collection, i can save the record in
main table (which is also a custom BO), get the primary key and save the
child table records accordingly.
B) Gridview does not allow insert and Gridview/Detailview will not show
ANYTHING if there is no data and not allow you even to insert. /**** Without
insert how you will get data and without data you cannot insert (What
Microsoft ASP.NET guru want to achieve with this merry-go-round i dont know)
****/.
C) By using custom collection I can add a empty object, so it show me dummy
record in Detailview with default values. Now user can atleast edit it, and
if they have more records they can carry on with insert.

Question:-

1) How in my business object class I will have access to the instance of
Collection class (created on webpage) to manuplate it?

NOTE:
my requirement is to update the data in collection only, WITHOUT affecting
the database. Let say user adds/edits/delete any of records in gridview, it
should only affect the Business Object (Generic Collection), after on final
submit i will update it to the database.

Thanks & any help would be highly appreciated.

Khuzema
June 30, 2005 10:59 AM
 

simon.evans said:

Khuzema

So, to summarise what I think you asking, what you are saying is that you want to be able to edit the properties of objects in a collection, and only commit updates to the database at the end of all the edits.

So, with that in mind, firstly, lets look at retriving objects from a collection, returned by your business process.

To do the select using a collection (such as a generic ICollection<T>, your ObjectDataSource will look something like this:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Get" TypeName="YourBusinessProcessNameSpace.YourBusinessProcess"></asp:ObjectDataSource>

Here, the code will execute the method YourBusinessProcess.Get to retrieve data from your business tier. I this example, the Get method will return a collection of type ICollection<T>. Note that the ObjectDataSource does not need to know this type in the markup; it uses reflection to obtain type for the resulting collection.

Next, you will have a control such as the GridView to display the contents of the collection. Each row of the grid view will automatically represent an item from your collection. The following markup gives you an idea of what to use:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" DataKeyNames="Id" >
<Columns>
<asp:BoundField Visible="true" DataField="Id" />
<asp:BoundField Visible="true" DataField="FirstName" />
</Columns>
</asp:GridView>

This GridView will show two properties of an object contained within the collection returned by the ObjectDataSource: Id and FirstName. If you were trying to access these properties programatically (in the first row), you would use the following code:

YourBusinessProcess.Get[0].Id;
YourBusinessProcess.Get[0].FirstName;

Now, to the update.....

If you to use the built in update functionality, the ObjectDataSource will force an update for each row as you edit it. You would add an Update attribute to the object data source, which contains the update method from the YourBusinessProcess class. Using the <asp:BoundField /> tag as above provides code free round trip binding. However, I understand that in your scenario that you want to batch update, like a DataSet DiffGram. In this scenario, you will need to provide your own code to do the batch update, either handed within your business process class, or by sub classing the object data source, or by not using the object data source to manage the update. If I were you, I would go for one of the latter you; sub classes the object data source will probably be the most elegent, but possibly the most work.

One final point. Using the <asp:BoundField /> tag is used for simple round trip data binding. In your scenario, you may be better off using the DataBinder.Eval statement, as this give your more control over what you bind to, but does not allow auto updates.

I hope this helps.

Simon
July 4, 2005 11:17 AM
 

TrackBack said:

September 5, 2006 6:08 PM
 

TrackBack said:

September 5, 2006 6:09 PM
 

jc said:

Thank you for this.  This really helped me understand some things.  This page would be even better if you added a few examples of how/when you might use each event.  Very good!!!!

October 30, 2007 3:44 AM
 

Madhu said:

Hey this decription gave me some idea.......... but i need to know how can i use filters in ObjectDatasource using Rad controls for Visual studio 2005 (web applications)........... thaks for this

December 9, 2007 10:40 AM
 

Netcougar said:

Thanks.  This helped!

December 27, 2007 3:16 AM
 

Andrew said:

FYI your ObjectDataSource does NOT need to have a default constructor. Just hook up the event ObjectCreating and set the e.Instance to whatever you want (depending on type, of course). This way you can instantiate your actual ODS object whenever in code and assign it here.

May 15, 2008 5:42 PM
 

shazia said:

It is really helped me and it is very important

December 17, 2008 11:21 AM
 

Pakistanjobspk said:

Good article.  This article is provide good and useful information.

May 9, 2009 12:35 PM

Leave a Comment

(required) 
(optional)
(required) 
Submit

About simon.evans

Simon is a Managing Consultant for Conchango in the UK, part of EMC Consulting Services. He is an expert in .NET development, and more specifically in WCF and ASP.NET, having participated in several Microsoft early adoption programs. Simon believes deeply that a broad understanding of key technology concepts is an essential foundation to being a gifted designer and builder of solutions.
Powered by Community Server (Personal Edition), by Telligent Systems