Data binding to strongly typed objects

A common source of error in ASP.NET development is mistyped data binding expressions. The reason for this, is that the expressions are not verified during compile time (together with the rest of our code), but first in runtime, when they are vastly more expensive to fix, time-wise.

Just to bring everyone up to speed, I am talking about these:

<asp:Repeater runat="server" id="attachments">
  <HeaderTemplate>
    <table>
  </HeaderTemplate>
  <ItemTemplate>
    <tr>
      <td width="220" ><%#Eval("FileName")%> (<%#Eval("MimeType")%>)</td>
      <td><asp:LinkButton runat="server" CommandName="delete" .../></td>
    </tr>
  </ItemTemplate>
  <FooterTemplate>
    </table>
  </FooterTemplate>
</asp:Repeatera>

Now, if I were to misspell either of the public property names of my data bound object (an instance of Attachment in this case), the solution would compile just fine, but errors would occur upon running the page. Also, if someone else later down the road wanted to update my page, they would have to find the data binding expression in the code behind file, to understand which object I was binding to.

As a way of making the above code more maintainable and easier to read, I suggest using strongly typed data binding. Not diving into the boiler plate code right away (how much fun is that?), here is the revised ASPX code:

<asp:Repeater runat="server" id="attachments">
  <HeaderTemplate>
    <table>
  </HeaderTemplate>
  <ItemTemplate>
    <%#SetDatabindingObject(Container.DataItem)%>
    <tr>
      <td width="220"><%#Attachment.FileName%> (<%#Attachment.MimeType%>)</td>
      <td><asp:LinkButton runat="server" CommandName="delete" .../></td>
    </tr>
  </ItemTemplate>
  <FooterTemplate>
    </table>
  </FooterTemplate>
</asp:Repeatera>

Here, we clearly see that we are working with an Attachment. Also, if we were to misspell one of the property names, the compiler would not let us off the hook. The third benefit of strongly typed data binding expressions, is the fact that now, our IDE can help us by providing Intellisense (although this does not always work still), which also helps us.

OK, the boiler plate code: I don't know if you noticed, but there was a new data binding expression added to the code above:

    <%#SetDatabindingObject(Container.DataItem)%>

This expression does not produce a value, but instead hooks up the protected Attachment field to reference the current data binding object:

    Protected Attachment As ProjectName.DAL.Attachment
    Protected Function SetDatabindingObject(ByVal DataItem As Object) As String
        Attachment = DirectCast(DataItem, ProjectName.DAL.Attachment)
        Return String.Empty
    End Function

The method simply receives the current DataItem as enumerated from the data source bound to our container (the repeater in this case), and casts it to a well-known object (Attachment). Then, it sets the protected reference and we're good to go.

I hope this helps. :-)

Comments

Popular posts from this blog

Auto Mapper and Record Types - will they blend?

Unit testing your Azure functions - part 2: Queues and Blobs

Testing WCF services with user credentials and binary endpoints