Click here to monitor SSC

Software Engineer at Red Gate Software, Maker of funky apps.

Why ASP.NET MVC is better – using ‘Hello’ as an example

Published 30 September 2009 10:12 am

In this second post about Hello (the first can be found here), I’m going to use one of the more complex portions of the app, the event front page, to illustrate some of the various parts of MVC which make writing web apps more intuitive.

The web app of the Hello project was written in ASP.NET MVC, which is Microsoft’s latest addition to the ASP.NET framework. It uses the Model, View, Controller design pattern and is influenced heavily by frameworks like Ruby on Rails.

Fig. 1 – The event front page of Hello displays the seating for the event; each chair is represented by a square and if there is a user in the chair we display their twitter avatar.

To produce the event page, there are several stages that the app goes through – for an awesome outline of the ASP.NET MVC Request-Handling Pipeline, see this poster. Firstly the URL is routed through to the correct controller. We decided that we wanted the front page for an event to live under a really simple URL: /eventslug, where eventslug would be a short string to uniquely identify the event. For example, for the Future of Web Apps event we might have the URL /fowa. From the event page you can search the users at the event, and we decided the intuitive URL for the search should be /eventslug/search. You configure the URLs in the Global.asax.cs file as follows:

routes.MapRoute(null,
"{eventslug}/{action}",
new { controller = "Event",, action = "Index", }, // Defaults
new { eventslug = Settings.EventSlugRegex } // Contraints
);

From here the framework calls an action on your controller. If you’ve not started using MVC yet, a controller in an object that inherits from the abstract class System.Web.Mvc.Controller and an action is a public method of a controller. The signature for our action that will be called for /fowa is:

public ActionResult Index(string eventslug)

We call it Index because that’s the default action that we specified in the routing configuration. The framework will automagically map the value of the eventslug argument to the value that matches the {eventslug} portion of the URL; In the case of /fowa it will be the string "fowa"*.

Then, in our action method, we grab the data relevant to the event with the requested event slug, and pass it to the view by calling View().

var theEvent = _repo
.Events
.SingleOrDefault(e => e.Slug == eventslug);
return View(theEvent);

Calling the View method with theEvent as an argument means that in the view, the Model property of the ViewPage object will be the theEvent that was just retrieved from the repo. In MVC the view is an aspx page without a code behind class. The view is actually a ViewPage<T> object, which is a subclass of the old Page object that you’re familiar with from WebForms, where T is the type of the Model property. What this means is that in the view we get intellisense on our domain object:

Fig. 2 – Intellisense in the view code on the statically typed Model property.

In the view we also have complete control of our HTML, which was invaluable for this page as we had to get the layout just right in all the major browsers. So we just iterate over our rows of seats rendering the smiley.jpg image for an empty seat (sat == null) and when someone is in a seat we render their Twitter avatar.

<table class="seatingPlan" cellpadding="0" cellspacing="0" border="0">
<% var sats = (IList<Sat>)ViewData["Sats"]; %>
<% foreach (var row in Model.Seats.GroupBy(s => s.Row)) { %>
<tr>
<% foreach (var seat in row) { %>
<td>
<% var sat = sats.SingleOrDefault(s => s.SeatID == seat.SeatID); %>
<% if (sat == null) { %>
<img src="<%= Url.Content("~/Content/images/presentation/smiley.jpg") %>" />
<% } else { %>
<img src="<%= sat.User.ImageURL %>" />
<% } %>
</td>
<% } %>
</tr>
<% } %>
</table>

This is much more intuitive and clear than having to create a user control class which is then dynamically instantiated in the code behind and added as a child control of an ASP TableRow, which is then in turn added to an ASP Table, etc. Your code in front would of been basically one line…

<asp:Table runat="server" ID="SeatsTable" />

… Totally hiding the complexity in the code behind, which would probably have been a mess of data access code and layout styling knotted together. Which is what you would have done in WebForms.

So why is this better? There are probably two key differences between WebForms and MVC. Firstly, separation of concerns: MVC encourages you to separate out your domain model from your UI from your URL routing. WebForms actually makes that quite difficult; if anything, the code in front/behind paradigm encourages the reverse. Secondly, no unnecessary leaky abstractions: WebForms tries to hide from the developer the fact that he is working in a world of string manipulation over a stateless protocol. In the simple case this can work well, e.g. the classic click-the-button-to-make-the-label-say-hello example. But in the real world, the abstraction soon gets in the way, and you end up having to work really hard to achieve something quite simple. In MVC there is no abstraction to battle against, you have complete control of all parts of your web app. I’m going to put myself out there and say that MVC should be seen as a replacement to WebForms, as I don’t think there are any real world cases when MVC is not the right choice.

* this isn’t strictly true, the arguments of an action can be mapped from 1 of three places – the URL, query string paramenters, or form values.

5 Responses to “Why ASP.NET MVC is better – using ‘Hello’ as an example”

  1. Anonymous says:

    good topic to see on the net first time goodie goodie goodie goodie goodie goodie goodie

  2. Anonymous says:

    Your alternative to a leaky abstraction is no abstraction. I’d prefer to replace a leaky abstraction with a _better_ abstraction.

  3. Anonymous says:

    Asp.net MVC is a abstraction as well. Every framework is. The difference is, in my opinion, that the MVC framework is a abstraction of the things that need to be abstracted. Who need a abstraction to write a simple span tag? Just take such a simple thing as model binding in asp.net mvc. It saves you so much left-to-right code and you don’t even think about it.

    So to say that asp.net mvc is not a abstraction is wrong, and I don’t think that was the authors intention eather. It just abstracts some different parts.

    Anyway, thanks for a nice article.

  4. Matt Lee says:

    Mattias, that is a very clear and insightful comment.
    I love your line “Who needs an abstraction to write a simple span tag?”, so true :o )
    Thanks for the comment.

Leave a Reply