AJ's blog

July 17, 2006

ASP.NET 2.0 DataBinding Examined

Filed under: .NET, .NET Framework, ASP.NET, C#, Software Development — ajdotnet @ 9:54 pm

The databinding in ASP.NET is something I have been working on earlier (see http://www.alexander-jung.net/artikel/databinding/default.htm, partly available in english). So it was quite logical to check out the new ASP.NET 2.0 features.

Databindung falls in two categories: Simple binding and complex binding. I’ll talk only about simple binding in this post, that’s more than enough ground to cover anyway. Perhaps complex binding and datasources will be covered later (if I’ve got somethinig worthwile to say).

First the facts, then the assessment. Let’s start with ASP.NET 1.x to be able to see the differences…

Simple binding is used to bind properties to data. This could be the text property of a label, the title property of an image, or any other simple property of any other server control. If you set the property of a control with ASP.NET 1.x and Visual Studio .NET 2003 the designer would generate code fragements like this:

Single control and within datagrid:

<asp:TextBox id=TextBox2 runat="server"

    Text='<%# DataBinder.Eval(timer1, "Interval") %>'/><asp:TextBox id=TextBox3 runat="server"

    Text='<%# DataBinder.Eval(Container, "DataItem.Name") %>'/>

The first argument to DataBinder.Eval is a component (in this case a timer which makes close to no sense in a web application…) or in case the control is contained in a list control (grid, repeater, …) it may be Container to denote the current row. Behind the scenes the ASP.NET runtime would generate code like this (stripped down for brevity):

private Control __BuildControl__control7()

{

    TextBox __ctrl;

    __ctrl = new TextBox();

    this.__control7 = __ctrl;

    __ctrl.ID = "TextBox3";

    __ctrl.DataBinding += new EventHandler(this.__DataBind__control7);

    return __ctrl;

}public void __DataBind__control7(object sender, EventArgs e)

{

    DataGridItem Container;

    TextBox target;

    target = ((TextBox)(sender));

    Container = ((DataGridItem)(target.BindingContainer));

    target.Text = Convert.ToString(DataBinder.Eval(Container, "DataItem.LegalName"));

}

As you can see, it’s all based on code generation and it only works one way. To get the data out of the textbox you need to roll up the sleves and prepare for some work.

Now let’s look at ASP.NET 2.0 with Visual Studio 2005:

With simple binding, one can no longer choose the artificial property “(DataBindings)” (there is a new one, named “(Expressions)”, but that’s not directly related to databinding in the sense we’re just covering). Rather one has to use the smart tag (the small little triangle at the upper right corner) “Edit DataBindings…”. This smart tag however is only available for controls that are contained in a DataBoundControl. For controls contained in list controls this is the case and therefore no difference. For single controls though one needs a new parent control, FormView in this case.
Apart from this the output of the designer looks quite similar:

within formview:
<asp:TextBox ID=”TextBox2″ runat=”server” Text=’<%# Bind(“id”) %> Enabled=”False” ReadOnly=”True”/>
within gridview:
<asp:TextBox ID=”TextBox3″ runat=”server” Text=’<%# Bind(“name”) %> />

There are some noteable differences: First (and of no consequence at all) is the shortened syntax. Second, there is two flavours: Eval and Bind. Eval is the same one way databinding as in 1.x, Bind supports two way databinding. The third difference is the setting of the enabled and readonly properties. This is due to the fact that formviews supports different templates (just like the grid). Now let’s look at the generated code:

private global::TextBox @__BuildControl__control13() {

    global::TextBox @__ctrl;

    @__ctrl = new global::TextBox();

    @__ctrl.TemplateControl = this;

    @__ctrl.ApplyStyleSheetSkin(this);

    @__ctrl.ID = "TextBox2";

    @__ctrl.Enabled = false;

    @__ctrl.ReadOnly = true;

    @__ctrl.DataBinding += new EventHandler(this.@__DataBinding__control13);

    return @__ctrl;

}public void @__DataBinding__control13(object sender, EventArgs e) {

    TextBox dataBindingExpressionBuilderTarget;

    FormView Container;

    dataBindingExpressionBuilderTarget = ((TextBox)(sender));

    Container = ((FormView)(dataBindingExpressionBuilderTarget.BindingContainer));

    if ((this.Page.GetDataItem() != null)) {

        dataBindingExpressionBuilderTarget.Text = Convert.ToString(this.Eval("id"),

            Globalization.CultureInfo.CurrentCulture);

    }

}

public IOrderedDictionary @__ExtractValues__control12(Control @__container) {

    OrderedDictionary @__table;

    TextBox TextBox2;

    TextBox2 = ((TextBox)(@__container.FindControl("TextBox2")));

    […] // other controls ommited

@__table = new OrderedDictionary();

    if ((TextBox2 != null)) {

        @__table["id"] = TextBox2.Text;

    }

    […] // other values ommited

    return @__table;

}

Now, the Eval part works essentially the same way it did in 1.x, registering a DataBinding event handler on the textbox and setting the value. Vice versa we have one method for the formview control that takes the values of all bound child controls and puts them into a dictionary. Again it’s fully based on code generation.

Assessment:

Now let’s see whether the new databinding lives up to the expectations. Well, there’s good news and bad news…

The good part: Imagine a web site structured like a “classical web site” (i.e. one containing lists, simple input forms, etc.). With ASP.NET 2.0 one can implement that without leaving the designer (provided the data is readily available). It’s actually quite amazing how far you can get without having to type code. And due to the code generation approach it’s fast and efficient and any faults will show up during compile time. If you ask me, that’s better than ever.

The bad part: Imagine a web site that is different in one or the other respect. It may have a UI that’s structured like a windows form with several user controls, each providing their own formview, yet they should work in unison. It may be that you shy away of the maintenance effort for several templates per formview and would prefer a meta data driven frontend. This could be controls that can render themselfs readonly rather than having to maintain two different templates. Or the data structures you use provide enough meta information to create validators dynamically.
Now you’re struck. You simply don’t have the informations you need. The textbox never knows which field it is bound to, so how do you retrive the meta data you need? The formview behaves at if it where the only one working exclusively on one whole row/entity, so how do you synchronize multiple formviews, each working on a partition of an entity?
The answer is: You can’t. Full stop.
The consequence: Forget your good ideas – or roll your own databinding.

Has Microsoft delivered something good?
In terms of functionality I think they have done quite a good job, they could hardly have delivered more.

Could Microsoft have done better?
In terms of design and how to surface the features to the developer they don’t live up to my expectations. In fact I wouldn’t call the databinding mechanism a framework feature because it lacks framework quality, in this case extensibility points. This is even more annoying since I know the can do better. MFC used code generation (read preprocessor macros) and yet was extensible; ATL used templates and yet was extensible. Other areas in ASP.NET use interfaces, methods, provider patterns – all valid extension points. I know they could have done better.

That’s all for now folks,
AJ.NET

Advertisement

7 Comments »

  1. This was the first reasonable, explicit, and concise description of what the Bind method does I have found on the web after searching for the info for about 3hs (5 mins ago I was thinking I would pay to see what the generated code was…).

    Thanks.

    BTW, seeing what this does, I decided to stay away from FormView/DetailViews.

    Comment by Juan Ignacio Gelos — January 6, 2007 @ 7:49 am

  2. Great! I knew about the way Eval is being used, but I was wandering how the go about Bind, now I know. I preferred not knowing 😦

    Comment by Michal Talaga — February 6, 2007 @ 7:58 pm

  3. ASP.net 2.0 Data Binding Internals

    Alexander Jung has a post outlining how ASP.net 2.0 data binding is implemented using code generation. A more detailed look at ASP.net 2.0 databinding internals is available at DotNetDan. Looking at the generated code, it surprised me that the Bind() m…

    Trackback by Chui's counterpoint — June 12, 2007 @ 3:42 am

  4. Excellent post and certainly helped clarify things. We want to be able to (pre or post) determine the textbox binding on a formview from what you are saying this is not possible. The best solution we have come up with so far is to include meta data within the datasource (we take the data in the object datasource and decorate it) and/or use hint mapping. We did the hint mapping via a custom control (custom textbox) but would prefer to be able to obtain the binding directly – any further information gratefully received.

    Thanks.

    Comment by Chris Sullivan — July 13, 2007 @ 4:00 pm

  5. […] Specifically for .NET 2.0 databinding, the most informative post I have found about the Bind() construction […]

    Pingback by Chivinou [ʃivinu] » ASP.NET FormView DataBinding with ObjectDataSource - Take 1 — February 26, 2008 @ 4:32 am

  6. Totally agree with the other posters. Something I thought would be so easy resulted in hours of searching. Finally came across this, works great. Thanks for posting this answer.

    Comment by Mike Welch — July 15, 2008 @ 8:57 pm

  7. Helpfull blog…

    Comment by rem — November 16, 2008 @ 10:10 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: