Evolution of a View in ASP.NET MVC

Posted by Joe Wilson on Wednesday, August 12, 2009 1:42 PM

Many developers prefer working with ASP.NET MVC over Web Forms because they are more connected with the HTML, have better control over the rendered output, and can easily build their own HTML helpers to get consistent output.

But making the views can be a hassle when your building a CRUD app or something that has a lot of very similar views.  Let's look at some ways around that you can use today and in the future.

Past

When MVC first came out, most people were coding their inputs in views like this.  Just straight HTML with some helpers:

<% using (Html.BeginForm()) { %>
	<fieldset>
		<label for="Name">Name</label>
		<%= Html.TextBox("Name") %>
		<label for="Email">Email address</label>
		<%= Html.TextBox("Email") %>
		<label for="Phone">Phone</label>
		<%= Html.TextBox("Phone") %>
		<%= Html.SubmitButton() %>
	</fieldset>
<% } %>

Simple, but a little too much reliance on strings.  This made the code error prone, so developers made their own HTML Helpers to crank out consistent views with fewer strings by using lambda expressions:

<% using (Html.BeginForm()) { %>
	<fieldset>
		<label for="Name">Name</label>
		<%= Html.TextBoxFor(c => c.Name) %>
		<label for="Email">Email address</label>
		<%= Html.TextBoxFor(c => c.Email) %> 
		<label for="Phone">Phone</label>
		<%= Html.TextBoxFor(c => c.Phone) %> 
		<%= Html.SubmitButton() %>
	</fieldset>
<% } %>

That's better.  We get IntelliSense for the model's fields and we get the leave some of the strings behind.

Present

The next step was to get rid of some of those label statements and get those rolled into the output automatically.  They did this in Code Camp Server and you can see the step-by-step progression in Eric Hexter's blog:

<% using (Html.BeginForm()) { %>
	<fieldset>
		<%= Html.Input(c => c.Name) %>
		<%= Html.Input(c => c.Email) %> 
		<%= Html.Input(c => c.Phone) %> 
		<%= Html.SubmitButton() %>
	</fieldset>
<% } %>

Nice!  Now we're on the road to consistent output in all forms in our MVC app and we won't spend as much time typing up view code.  Eric even shows us he can name that view in one note:

<%= Html.InputForm() %>

Future

If you've been following the latest on ASP.NET MVC, you've seen the announcement for MVC 2 Preview 1 here, here, and here.  Microsoft is going the same direction as these open-source extensions and making it easier to get a consistent view rendered:

<% using (Html.BeginForm()) { %>
	<fieldset>
		<%= Html.LabelFor(c => c.Name) %>
		<%= Html.EditorFor(c => c.Name) %>
		<%= Html.LabelFor(c => c.Email) %>
		<%= Html.EditorFor(c => c.Email) %> 
		<%= Html.LabelFor(c => c.Phone) %>
		<%= Html.EditorFor(c => c.Phone) %> 
		<%= Html.SubmitButton() %>
	</fieldset>
<% } %>

MVC 2 also has an almost one-liner form that you define with templates, one of the new features:

<% using (Html.BeginForm()) { %>
	<fieldset>
		<%= Html.EditorFor(c => c) %>
		<%= Html.SubmitButton() %>
	</fieldset>
<% } %>

So we've seen views getting simpler and smaller and even one-line forms.  Can it get any smaller than a one-line form?  What if there was no view?  Can you have a view with zero lines of code?

Kind of.  Phil Haack took the MVC 2 Preview 1 code out for a spin to try what he calls "default templated views".  The idea is that your controller gets a model and displays a virtual view by using templates from your web project's "~\Views\Shared" folder.  You can make as many templates as you need for different purposes.

This is ideal for CRUD apps or places in your app where the view is the same except for the model data it renders.  You don't need a physical file for each view other than the template itself.  The controller just renders a view that is one of the shared views/templates.

I like this approach because you can crank out code more quickly for the easy stuff, but if you have a view that needs something more complex, you still have the normal HTML inputs and helpers to fall back on.  I hope Microsoft gets this idea fully flushed out and it ends up in the final MVC 2 release.  It would make developers more productive on repetitive views and would have wider acceptance if it was in the MVC base-class libraries.

Tags: MVC, Html Helpers
Categories: Technical

blog comments powered by Disqus

Blog links

  • Subscribe to this blogRSS feed
  • Archive of old posts

Popular posts

  • Autocomplete dropdown with jQuery UI and MVC
  • Handling Exceptions in ASP.NET MVC
  • Don't mock HttpContext
  • Review of Sharp Architecture
  • Evolution of a View in ASP.NET MVC
  • Comparison of Typemock Isolator and Rhino Mocks
  • Building a Windows 8 Live Tile with JavaScript
  • Setting Default Values for Multiple Value Parameters in Reporting Services
  • Buy, Build, or Both?
  • Why bother writing unit tests?

Tag cloud

  • AppHarbor
  • Areas
  • ASP.NET
  • ATDD
  • BDD
  • Castle Windsor
  • Coding Standards
  • Common Service Locator
  • continuous integration
  • Cookies
  • CRM
  • CSS
  • Custom Software
  • Data Annotations
  • DataTables
  • DDD
  • Dell
  • Dependency Injection
  • DTOs
  • ELMAH
  • git
  • GitHub
  • Html Helpers
  • HttpContext
  • IOC
  • iPad
  • iPhone
  • JavaScript
  • jQuery
  • jQuery Mobile
  • JSON
  • Kendo UI
  • Knockout
  • Microsoft Accounting
  • Moq
  • MVC
  • NHibernate
  • NuGet
  • NUnit
  • OData
  • optimizations
  • Patterns
  • POCOs
  • QuickBooks
  • Rails
  • Refactoring
  • Reporting Services
  • REST
  • Rhino Mocks
  • Session
  • Sharp Architecture
  • SOLID
  • SpecFlow
  • SQL Server
  • SSRS
  • TDD
  • TeamCity
  • TempData
  • Typemock
  • unit testing
  • Validation
  • Visual Studio
  • VMWare
  • WatiN
  • WCF
  • Web API
  • Web Essentials
  • Web Forms
  • Windows 7
  • Windows 8
  • WinJS

Archive

  • 2013
    • May (1)
    • April (1)
    • March (1)
    • February (3)
    • January (1)
  • 2012
    • December (1)
    • October (6)
    • September (3)
    • March (1)
  • 2011
    • October (1)
    • August (1)
    • June (3)
    • March (2)
    • February (2)
    • January (4)
  • 2010
    • December (2)
    • October (3)
    • September (1)
    • August (2)
    • July (1)
    • May (1)
    • April (2)
    • March (2)
    • February (3)
    • January (2)
  • 2009
    • November (3)
    • October (2)
    • September (5)
    • August (2)
    • July (3)

Blogroll

  • RSS feed for Dan WahlinDan Wahlin
  • RSS feed for Jimmy BogardJimmy Bogard
  • RSS feed for John PapaJohn Papa
  • RSS feed for Josh TwistJosh Twist
  • RSS feed for Los TechiesLos Techies
  • RSS feed for Phil HaackPhil Haack
  • RSS feed for Scott GuthrieScott Guthrie
  • RSS feed for Scott HanselmanScott Hanselman
  • RSS feed for Steve SandersonSteve Sanderson

Twitter

  • Twitter May 15, 7:20 PM

    At Denver .NET meetup to hear @rlacovara talk about SpecFlow

  • Twitter May 15, 9:26 AM

    @eriklane @extofer @greeleygeek That sounds weird to me, too. Values on the query string, sure, but not JSON.

  • Twitter May 15, 9:24 AM

    @kevinkrueger otherwise, people will not be as forthcoming about areas they hope the team can improve

  • Twitter May 15, 9:24 AM

    @kevinkrueger I think retros are best if they are for the team only, so they can have a frank discussion of how to get better.

  • Twitter May 14, 10:49 AM

    Terrific talk from @zekeli @html5denver last night "Cross domain Pong with window.postMessage" http://t.co/iO0AAlbJ7l http://t.co/5mnf2fZL0p

  • Follow me on TwitterFollow me on Twitter

Recognition

  • INETA Community Champions

Blog license

  • Creative Commons License
    Blog by Volare Systems is licensed under a Creative Commons Attribution 3.0 Unported License.
    Based on a work at http://volaresystems.com/blog/.