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.