NerdDinner.com and Two Views of ASP.NET MVC Views

Phil and Scott  (and the other Scott) announced the open source Nerddinner.com project and their free ASP.NET MVC eBook today. Actually, the free eBook is a single chapter of 185 pages, which is at least 50 pages longer than any chapter in Tolstoy’s War and Peace (and over half the size of my entire workflow book). Amazing.

In any case, I was looking through the code this evening and a thought struck me. You can divide the nascent world of ASP.NET MVC developers into two camps:

Taxonomy of String People

The people who use strings don’t love to use strings – they just use them to get work done. But the people who hate strings really hate strings. They’d rather be caught using goto label than ever type a string literal, and they exterminate string literals from as many places as possible.

The views in Nerddinner.com are full of strings:

<p>
    <label for="Title">Dinner Title:</label>
    <%= Html.TextBox("Title", Model.Dinner.Title) %>
    <%= Html.ValidationMessage("Title", "*") %>
</p>

The “Title” string is significant – it has to match up with the name of a controller parameter or the name of a model property when data movies in and out of the controller. A typo in the view, or in a model, can create bugs. Compare the “stringy” views to the views in another open source MVC application - CodeCampServer:

<%=Html.Input(a => a.AttendeeID)%>
<%=Html.Input(a => a.ConferenceID)%>

This is another example of using LINQ expressions to implement “reflection without strings”. A typo here yields a compiler error. The technique is quite powerful and implementations are popping up everywhere, including inside the MVCContrib project.

Errors can be caught with either approach, but you can catch errors earlier and perform safer refactorings if you take Nancy Regan’s advice and Just Say No (to magic strings).

I’m curious – which approach do YOU prefer?

Print | posted @ Wednesday, March 11, 2009 5:32 AM

Comments on this entry:

Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Stan at 3/11/2009 6:09 AM

What's the performance impact of using those linq expressions? Don't they have to compile each one? Seems like that could be a hefty price to pay.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Scott Hanselman at 3/11/2009 6:37 AM

Ya, I went back and forth on this. In this case, the "Title" is really the name of the Field, so it could be "Poo," but as you point out it's coincedentally (and conventionally) the name of the field. I would want to really perf test the strongly typed stuff, but I think it's good we have the choice.

My personal opinion is this. Compilation is just the FIRST Unit Test. I feel *less bad* about using Strings when I have great Unit Tests. They will catch my goofs. If they don't, I need more tests.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Haacked at 3/11/2009 6:37 AM

We also have expression based helpers in the MvcFutures project.

I have to admit, I like strings. After all, what is it exactly that we're sending down the wire. Strings!

Then again, I also like the expression-based helpers. They give you nice Intellisense and refactoring support.

But ultimately, we have to face the fact that we need to test the UI and that strong typing is not a panacea.

For example, even with expression based helpers. What happens when I include a bit of jQuery that modifies an element by name or ID. A refactoring is not going to catch that.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Gunnar at 3/11/2009 8:20 AM

I prefer stringless approach.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Samuel Jack at 3/11/2009 9:38 AM

I do my best to avoid using strings, especially when calling raising Property Changed events.

Jafar Husain has a nice pair of articles about using lambda expressions to do this in C#3.0:

themechanicalbride.blogspot.com/...

themechanicalbride.blogspot.com/...

  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by ILog at 3/11/2009 10:50 AM

I loved objects before starting web programming. Now I love strings, but hate when the rules of their usagage are non-humanic :)
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Joshua Flanagan at 3/11/2009 12:36 PM

I would guess that the divide closely matches up with "people that live by ReSharper, and those that dont".

We go the static reflection route for all strings that have a "meaningful" value. A string is meaningful in this context if its value has to exactly match up with a property/parameter name in compiled code.
To answer Phil's question - our static reflection helpers do not auto-generate element IDs to be used with jQuery. If we need to target an element for jQuery, we will tack on an ID using a regular string - because that string is not meaningful to the compiled code, it only matters to the javascript.
Ex:
TextBoxFor(a => a.AttendeeName).ElementID("attendeeNameInput")

In this case, the name attribute of the input is generated, because it must exactly match up with the AttendeeName property on the model. But the ID attribute is just a string that has to match with string used in the javascript.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by alberto at 3/11/2009 1:26 PM

+1 on strongly typed. Oh, and you meant lambdas, not LINQ. ;)
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by scott at 3/11/2009 2:26 PM

@Stan: I don't know the performance impact. Would be interesting to measure, as it does require quite a bit of code to inspect the expressions (and yes they do get .Compiled).

@alberto: I only say LINQ because the Expression<T> class lives in System.Linq.Expressions.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Hernan Garcia at 3/11/2009 4:15 PM

I don't mind using strings for fields id's or any other view element but I try to avoid using magic strings that have to be translated into code like the action of a controller if I can. On performance issues. In this particular scenario I will heavily cache the views anyway, so I won't be worry about it. In other context may be an issue, but as with everything it needs to be measured. And yes you still need to test everything. I guess the string debate has more to do with having proper support for refactoring tools than anything else in my case. I'm thinking more and more than views should use some dynamic language anyway but that is another issue.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Andrew Gunn at 3/11/2009 4:27 PM

I prefer using the LINQ expression approach - it makes everything more robust. You can even do the same for form/anchor tags and point them to specific controller actions.

The string alternative is handy on Views that haven't been strongly typed, but this should be frowned upon in itself.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by george at 3/11/2009 6:44 PM

I prefer strings I guess, but to avoid typo's I always put the strings as constants/variables in a centralized "storage", e.g. a set of common-classes. So your string-sample would look something like:

<%= Html.TextBox(StringKeys.Title, Model.Dinner.Title) %>
<%= Html.ValidationMessage(StringKeys.Title, "*") %>
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Kevin Dente at 3/11/2009 7:32 PM

@ScottHa,
"I feel *less bad* about using Strings when I
have great Unit Tests"

Really? So you have unit tests for your views? I don't see any in the source.

  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Eric Hexter at 3/11/2009 7:46 PM

I fall in the strongly typed camp.... strings are bad and I am really bad at typing the same string multiple times. I need the refactoring support supplied by strongly typing my view helpers.

  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Bahador at 3/11/2009 8:14 PM

I really hate strings ;)

On the other hand, if there is enough unit tests in the framework *and* you can discipline your team into writing them when adding new features, the strings are acceptable.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Jeffrery Palermo at 3/12/2009 2:45 AM

Hehe. You know where I fall. Eric Hexter and I did the Html.Input() CodeCampServer views. Works out nicely and drives ModelState validation as well.

Once Dynamic Data comes out, we'll be able to delete a lot of code driving that.

The expressions also help to drive WatiN tests for full system testing. Otherwise those tests are brittle
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Bryan Watts at 3/12/2009 6:07 AM

I want language support for static reflection, to which all this is an approximation.
  
Gravatar # re: NerdDinner.com and Two Views of ASP.NET MVC Views
by Blargo at 3/12/2009 4:38 PM

<%=Html.Input(a => a.AttendeeID)%>

In my opinion that is pretty obscure. What does that generate? A text input with the numeric attendee ID? Why would you ever let a user directly edit that? What does the 'a' variable stand for? Are there built-in error validation messages? Does the Input method generate a label also? If so, where does it get it's caption from?

While this might win points for fewest characters typed, it's not readable or understandable at all. Look, you may think you're clever and obtuse and what not, but what about the guy who has to come through later and read your lambada-infused (abused is more like it) "shortcut" code?

BARF.


  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 3 and 5 and type the answer here: