Thursday, April 29, 2010

More Thoughts on ASP.NET MVC

I've had two months to work with ASP.NET MVC since my last post on the topic.  Since then, I've worked through two projects and have picked up some good experience.  There are plenty of pros and cons (more pros in my opinion).  Let's take a look at how it differs from other .NET web technologies.

Routing
ASP.NET MVC is more than just Model-View-Controller pattern (the MVC which lends its name).  One of the key features is routing.  With routing, a URL does not point to a physical resource on the server.  Instead, it contains information that allows the Controller to instantiate the appropriate Model and send the data to a specific View.  You're probably familiar with the pattern.  Let's take a look at the URL for my previous post: http://jeremybytes.blogspot.com/2010/02/new-to-me-aspnet-mvc.html.

The first part is (http://jeremybytes.blogspot.com) points to the server.  The next part (2010) would normally be parsed as a physical path (file folder) on the server.  But instead, it is a parameter that references the year of the post.  The same is true of the "02" portion (the original post is from February 2010).  The final part is the name of the article.  Now, I can't tell you what lies behind the blogspot link or how it is parsed, but I'm pretty sure that there are no physical directories that refer to the year and month of my posts.

You use this same type of routing in the ASP.NET MVC world.  The default is for a URL to take the form of {controller}/{action}/{id}, but you can alter this default implementation however you like.  As an example: http://www.example.com/sales/customer/217.  This would call the "Sales" controller and ask for Customer #217.

As mentioned previously, this is an "action-first" or "resource-first" model (as opposed to WebForms "page-first" model).  I say "action" or "resource" because that will depend on what you are doing.  In the above example, we are requesting a specific Customer resource.  But we could just as well be requesting an action, such as "UpdateCustomer".

This strikes me as very REST-ful, although that is a topic for another time.  The good news for those who like the idea of routing but aren't ready to dive into the rest of ASP.NET MVC: Routing is included in ASP.NET 4.0 (it's actually also available somewhat in 3.5 but requires some extra work).

ASP.NET MVC vs. WebForms: Repeaters
I spent 3 years developing WebForms apps, so I've tried quite a few different techniques for displaying data.  The control I ended up liking best is the Repeater.  This gives me the most flexibility in laying out my data.  But it does have one severe limitation: you cannot nest Repeaters.

The idea of a Repeater is that it will loop through your data set and "repeat" a specified section for each record.  This is fine for single level lists, but it gets more complex when you have parent-child relationships.

Let's say that I have data that includes Category, Sub-Category, and Details.  I only want to display the Category label at the top of each Category (not on each record).  The same is true for Sub-Category.  But since I can't nest Repeaters, that means that I must include Category, Sub-Category, and Detail in every single one of my records (flattened data rather than a hierarchy).  Then, to get the display that I want, I hook into the Event that runs before displaying each record.  In that event handler, I check to see if the current Category is the same as the Category of the previous record.  If so, then I suppress (hide) the Category display.  Same for Sub-Category.  This creates quite a bit of messy, conditional code.

ASP.NET MVC handles this situation entirely different.  You are much closer to the metal.  So, if I wanted to implement the above scenario, it's quite a bit more elegant.  In the View, I simply have a foreach loop that goes through all of the Categories and displays the Category header.  Inside there, I have a nested loop that goes through the Sub-Categories and displays that.  And inside there, I have a nested loop that goes through the details.  This means that I can have a much more natural structure to my data (Model) with a parent-child-grandchild relationship.  Add some LINQy goodness, and you have an easily understandable solution without the messy conditionals.

ASP.NET MVC vs. WebForms: File Size
Yes, file size is still important -- just take a look at how prominent smart phones and other mobile devices are becoming.  I took an existing WebForms application and converted it to ASP.NET MVC.  This was a proof-of-concept so I could try out the technologies.  Since the existing application had a well-defined business layer and clear separation from the UI, it was easy to put the ASP.NET MVC front end in place.

Here's what I found: a particular page on the WebForms apps that was 24KB was only 9KB in the ASP.NET MVC version!

I know your initial reaction: just turn off ViewState, moron.  But ViewState was turned off.  The WebForms page is so much bigger because it uses server-generated names for all of the controls.  This can look like "ctl00_mainRepeater_headerLabel_001".  When you multiply this by the number of controls for each record and the number of records in the data set, it all adds up.

Conversely, the majority of the ASP.NET MVC output is text -- the equivalent of using a Response.Write instead of using a server-side control.  When you look at the output (view source in the browser), it looks like hand-coded HTML rather than machine-generated code.  This will vary depending on how you code up your Views, of course.  My experience is that the output is pretty straight forward compared to WebForms output.

ASP.NET MVC vs. Silverlight
I won't really get into this debate.  Both technologies have their uses and benefits.  I was recently listening to .NET Rocks! and heard about a "challenge" that took place at the Visual Studio 2010 Launch Event.  Apparently Phil Haack (and team) and Rocky Lhotka (and team) were tasked with creating an application in ASP.NET MVC and Silverlight, respectively.  I have a great deal of respect for both of these guys, so I'll just leave that discussion there.

After using Silverlight myself, I was determined that I would never create another WebForms app again (the programming style is just so much more natural).  But there is a problem (mentioned above): mobile users.

The reason that I started using ASP.NET MVC is because I needed to create a solution for Blackberry users.  And I'm not talking about the shiny-new Blackberry Bolds.  I'm talking about (relatively) old devices with browsers that are a step above WAP.  Obviously, Silverlight was not an option.  ASP.NET MVC, however, allowed me to put together a clean and efficient application.

One Last Thing: Parameters
There are a number of things I like about ASP.NET MVC, but I'll wrap up with one item: Action parameters.  The ASP.NET MVC framework does everything it can to automatically pull in the parameters for you.

Let's say that I have an Action (method) like this: UpdateCustomer(int Id, string firstName, string lastName).  When this method gets called, the framework tries to populate the parameters from the following locations:
  • Routing Parameters: These are the parameters that appear as part of the URL "path", such as the "217" in the Customer example above.
  • Query String: These are additional parameters that are part of the URL query string.  These are separated from the rest of the URL with a question mark and take the form name=value (separated by ampersands).
  • Form Data: These are pulled from fields that are posted back in a form.
  • Post Parameters: These are the parameters provided as part of a POST (not necessarily part of a form).
  • Header Information: These items can be pulled from the request header.
If the framework can find matching, case-insensitive names that match the parameter names, it will pass them through to your method.  There's something about this that strikes me as very cool -- anything that makes my life easier is good.

Wrap Up
I've grown to like ASP.NET MVC.  At a later date, I'll put together a case study with my actual code to give you a better idea of exactly how the technology works.  For now, we'll just stay with what we've discussed so far.

ASP.NET MVC 2 is now shipping as part of Visual Studio 2010.  I've only taken a cursory look at it, but it seems to have added some good features to make views even easier and cleaner to generate.  Plus, having it included in Visual Studio means that other members of your team will also have it available without having to install the bits separately.  If you're doing web programming, this is definitely something to look into.

Happy Coding!

No comments:

Post a Comment