I was trying to put together a quick piece of code as an example over the weekend and remembered how much I dislike using DataBinder in ASP.NET.
Let’s say a web service call gives back an array of simple objects (the sort of objects you’d see imported by a web reference):
class Parameter { public string Name; public string Value; }
I wanted to dump the Parameter array to a web page as easily as possible. The following will not work.
<asp:Repeater id="Repeater1" runat="server"> <ItemTemplate> <tr> <td> <%# DataBinder.Eval(Container.DataItem, "Name") %> </td> <td> <%# DataBinder.Eval(Container.DataItem, "Value") %> </td> </tr> </ItemTemplate> </asp:Repeater>
The DataBinder, besides looking awkward, only finds public properties - it doesn’t find public fields. The quick hack to get around this is to replace the language agnostic DataBinder syntax with C# code:
<asp:Repeater id="Repeater1" runat="server"> <ItemTemplate> <tr> <td> <%# ((Parameter)(Container.DataItem)).Name %> </td> <td> <%# ((Parameter)(Container.DataItem)).Value %> </td> </tr> </ItemTemplate> </asp:Repeater>
Disadvantages:
There is a huge disadvantage in that if the Parameter class fields ever change, the code in the ASPX won’t generate an error until runtime. It’s also a problem if the ASPX moved from a C# project to a VB.NET project.
Advantages:
To me the second example looks cleaner – I can see an object and a property even through the parentheses of a cast. It’s also blazingly faster - two order of magnitude faster. In fact, in my tests the following:
<%# DataBindParameterName(Container.DataItem) %>
// in the code behind of the class: protected string DataBindParameterName(object o) { return ((Parameter)o).Name; }
is still 300x faster than the reflection machinations DataBinder.Eval uses. Food for thought in perf critical scenarios.