Databinding Tips: Nesting Eval Statements

0 comments suggest edit

Maybe this is obvious, but it wasn’t obvious to me. I’m binding some data in a repeater that has the following output based on two numeric columns in my database. It doesn’t matter why or what the data represents. It’s just two pieces of data with some formatting:

42, (123){.console}

Basically these are two measurements. Initially, I would databind this like so:

<%# Eval("First") %>, (<%# Eval("Second") %>)

The problem with this is that if the first field is null, I’m left with this output.

, (123){.console}

Ok, easy enough to fix using a format string:

<%# Eval("First", "{0}, ") %>(<%# Eval("Second") %>)

But now I’ve learned that if the first value is null, the second one should be blank as well. Hmm… I started to do it the ugly way:

<%# Eval("First", "{0}, ") %> <%# Eval("First").GetType() == 
  typeof(DBNull) ? "" : Eval("Second", "({0})")%>

*Sniff* *Sniff*. You smell that too? Yeah, stinky and hard to read. Then it occured to me to try this:

<%# Eval("First", "{0}, " + Eval("Second", "({0})")) %>

Now that code smells much much better! I put the second Eval statement as part of the format string for the first. Thus if the first value is null, the whole string is left blank. It’s all or nothing baby! Exactly what I needed.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

24 responses

  1. Avatar for Scott Muc
    Scott Muc April 12th, 2007

    Great tip! I've found myself checking for NULL in my ascx/aspx files and always thought it seemed wrong. Your way looks nice and elegant.

  2. Avatar for Kevin Dente
    Kevin Dente April 12th, 2007

    Hmm...shouldn't that bit o' logic be in a presenter, so it can be unit tested? ;)

  3. Avatar for Karthik
    Karthik April 12th, 2007

    I always end up putting such wacky formatting for repeaters inside a codebehind method that simply outputs the string I want.
    That way rather than fix it in multiple places when my client inevitably asks to change the format its easy to maintain.
    Case in point, I was using "N/A" to denote blank and my client wanted it changed to an image. Because the return of N/A was wrapped in a method I just had to change the method to return an <img> tag.

  4. Avatar for Haacked
    Haacked April 12th, 2007

    @Kevin: Well there's a fine line. For formatting stuff, especially stuff that changes a lot, I don't like to put it in code. For example, I don't unit test my CSS. I don't consider this "logic" as much as formatting. Though it really straddles the line.
    @Karthik: I wanted to avoid having to write a bunch of one-off methods that would require me to recompile the app just for a minor formatting change.

  5. Avatar for Kevin Dente
    Kevin Dente April 12th, 2007

    Phil,
    I hear ya. For me, when I hear "if x then y else z", I think "logic", and I'd rather have it tested. Plus, I'd rather capture that requirement ("the second thing isn't displayed if the first thing isn't") somewhere - the natural place being a test.
    But I agree, it's a fine line.

  6. Avatar for Haacked
    Haacked April 12th, 2007

    Well everything is an "if" statement.
    "If this div has a css class of blah, then make the background fuscia."
    ;)

  7. Avatar for Kevin Dente
    Kevin Dente April 12th, 2007

    That's it, I'm going to go start writing CSSUnit.
    :P

  8. Avatar for Scott Muc
    Scott Muc April 12th, 2007

    A CSSUnit would be a godsend! Imagine writing CSSUnit tests that spec out a layout and dimensions and then a test would fail because you forgot a child element inherited some padding you placed on some outer element. One can dream I guess...

  9. Avatar for Haacked
    Haacked April 12th, 2007

    Setting up the CSSUnit tests would be as time consuming as writing the CSS itself.
    I can see it now.
    Client: "Wait, I want you to move that two pixels to the left. Hmm.... No. Let's move it one pixel to the right and double the border. Hmm... Now that I see it. No, let's make that background slightly more yellow and move it right one pixel to where it was."
    You: "AAAAAAGGHHH!!!!" *rips hair out of head*
    The only CSS Unit test that would be useful is perhaps generating a test off of a Photoshop layout. But then, you'd probably never pass that test.
    Client: "Hey, the text isn't antialiased like the photoshop mockup. I want it to look *exactly* like the mockup."
    You: "AAAAAAAAIIEEEEEEEEEEEEE!!!" *staples hand with stapler*

  10. Avatar for Kevin Dente
    Kevin Dente April 12th, 2007

    Clearly those are "acceptance" tests. That's another thing entirely. :P
    The best way to automate those are...a boot to the head.

  11. Avatar for German Rumm
    German Rumm April 12th, 2007

    I like you "ugly" solution more. It clearly expresses logic - "if first value is not null, then display second"
    I wouldn't use a ternary there, simple "if" would be much better.
    But your solution is much prettier, yes.

  12. Avatar for kevin
    kevin April 12th, 2007

    I agree with Karthik - I have a utility class that handles this just in case I need to make across the board changes - its all done in one place.
    I here what phil is saying about having to recompile though as well.
    this is where the design decisions come into playe.
    for me, the utility methods are both easier to read and provide more "utility" because how often do you need to change something that is pretty much a standard - ie if its empty then display "na", for example.
    love the blog!

  13. Avatar for Dflying Chen
    Dflying Chen April 12th, 2007

    摘要本期共有6篇文章:ASP.NET编译问题的公开Hotfix补丁期待下个版本AjaxPro的发布在ASP.NET2.0中使用MultiView控件实现多页面表单数据绑定的技巧:嵌...

  14. Avatar for Filini
    Filini April 12th, 2007

    I, too, prefer to use a separate layer to prepare my data for layout.
    In the project I work at the moment, the Data returned by my services is transformed in a DataTable with all the right "strings" for layout presentation, and this DataTable can be databound to a Repeater, or a DataList, or a DataGrid depending on the situation.
    I found this approach very easy to mantain, over the years.

  15. Avatar for Samyi
    Samyi April 12th, 2007

    Good!

  16. Avatar for Dflying Chen
    Dflying Chen April 13th, 2007

    本期共有6篇文章:

  17. Avatar for shoutor
    shoutor April 13th, 2007

    ASP.NET编译问题的公开Hotfix补丁 <br />期待下个版本AjaxPro 的发布 <br />在ASP.NET 2.0中使用MultiView控件实现多页面表单 <br />数据绑定的技巧:嵌套Eval语句 <br />在ASP.NET 2.0中访问并更新数据:使用数据源控件以编程方式访问数据 <br />ADO.NET连接池一瞥

  18. Avatar for ljianl
    ljianl April 15th, 2007

    这个 有点新鲜 ,呵呵 。。。

  19. Avatar for lb
    lb April 15th, 2007

    >that code smells much much better!
    You think !?!?!
    >looks nice and elegant.
    ?? Whu!?
    you're all blind! crazy! wacko! that code is stinky! wrong! nasty, tricksy! and i don't like it a heck of a lot.
    >I don't consider this "logic" as much as formatting
    huh?? sounds like humpty-dumpty way of thinking doesn't it?
    CssUnit -- interesting idea ;-)

  20. Avatar for David Crowell
    David Crowell April 15th, 2007

    I rarely use databinding, so I was unaware that null would work that way in a bound control. I like it. I too have been resorting to helper methods in the page class.
    Thanks for the tip.

  21. Avatar for Jason
    Jason April 26th, 2007

    CSSUnit, hmmm, good luck on that one! IE6 quirks mode, IE7 partially fixes quirks mode but still has issues like height problem with floats etc. Just firing up a microsoft browser would fail the tests!...
    but the test names would be cool.
    AssertThatFirefoxCorrectlyRendersPngAlphaCorrectForBackGroundDivsAndThatIE6FailsMiserablyYetIe7SortaWorksSometimes()
    TestThatQuirksModeIe6WorksButNowSomeQuirksWereFixedInIe7SoTestAnotherHackCssTrickForMicrosoftIncompetenceInStandards()
    Css and browser compliance is black magic, and only Amazonian Voodoo doctors should attempt to unit test it.

  22. Avatar for StefanVE
    StefanVE May 14th, 2007

    I usually start out with Evals in the aspx. Then things get more complex and I decorate a property to handle the logic.
    Next I start thinking I am having too many Evals so I start using the code behind model (as you only have to cast the object once while Eval performs a cast each time).
    In the end I'll end up by replacing the repeater with a rendered control (for the extra flexibility) and start wondering where all my time has gone.

  23. Avatar for Jacky_xu
    Jacky_xu November 26th, 2007

    要本期共有6篇文章:ASP.NET编译问题的公开Hotfix补丁期待下个版本AjaxPro的发布在ASP.NET2.0中使用MultiView控件实现多页面表单数...

  24. Avatar for Mehdi Entezary
    Mehdi Entezary March 26th, 2008

    Many Thanks,
    I was trying to call a JavaScript function which would get 3 parameters. This trick did the job. Thanks.