Why MVC for ASP.NET?
Posted by Jonathan Allen on Dec 06, 2007 06:26 AM
Rick Strahl starts his look at Web Forms and MVC for ASP.NET by talking about its strengths. He claims that Web Forms have been proven to be a very stable and mature platform. Even in high performance scenarios, it is rare to have major scalability issues. At the same time, it is really easy to get started with. Rick continues,
Microsoft designed the entire Visual Studio Web eco-system to provide an easy development experience with drag and drop functionality on a visual designer with property sheet support. Developers write code to respond to events, which provides a fairly straightforward model for hooking up application logic that feels natural if somewhat un-Web-like. This model provides a high level of abstraction that is great for getting started, but it’s also problematic because it separates the developer from the low level Web mechanics in many ways. I’ll come back to this flip side a little later.
He concludes by mentioning how extensible the framework is and offers a nod to the large custom control industry. (There are probably more custom control vendors for ASP.NET than all other web platforms combined.)
Rick then turns to the downside of the very abstraction he praised earlier.
This is both a blessing and a curse. Web Forms allow developers to rapidly create applications simply by dragging and dropping controls and handling page-level events for both the page and the controls on the page. This works well, but it’s a high-level of abstraction and many developers completely forget—or never learned—how the HTML layout actually works behind the scenes. As a result, it’s common to end up with non-validating HTML, or bloated and hard-to-manage HTML layout that is very designer unfriendly. Add to that a huge amount of ViewState if you don’t effectively manage ViewState properly and you can easily end up with pages that are much bigger than they need to be and slow as molasses.
One downside of the Web Forms framework is that behind this abstraction layer, Microsoft built a very complex engine that has many side effects in the Page pipeline. If you’ve ever built complex pages that contain many components on the page it can sometimes get very difficult to coordinate the event sequence for data binding, rendering, and setup of the various controls at the correct time in the page cycle. Do you load data in the Init, Load or PreRender events or do you assign values during postback events? Web Forms need to run through a single server-side form so they can’t easily be broken up into smaller logical units. In complex forms, event handlers can get very bulky with the tasks they need to handle and often in ways that can’t be easily refactored so you end up with code that is difficult to maintain and impossible to test.
He goes on to discuss the problems with ViewState, event management, and post-backs in detail. Asp.NET developers who are not already intimately familiar with these topics owe it to themselves to study his words carefully.
One issue that will probably surprise our non-.NET developers is that it is very hard to determine a controls ID at design time. Short of relying on some fragile and undocumented naming container chain, there is no static way to know that a control called "txtPassword" actually has an id of something like "PublicSiteTemplate1_ctl00_txtPassword". And this is a relatively short id on a simple page.
The cryptic control ids and sensitivities of ViewState become a serious problem for so-called Web 2.0 sites. The only framework that does not have serious ViewState corruption issues is ASP.NET AJAX. But it is an immature library.
To me, Microsoft AJAX in general is not a great client-side library solution in the first place. It’s big, not very modular and provides only limited functionality for the client-side developer with the client framework being more of a core framework/reference implementation than a useful API library that provides usable functionality for client-side scripting. If you compare it to the lean and mean and highly functional approach of libraries like jQuery, Prototype, MooTools , and so on, Microsoft AJAX feels like it’s seriously lacking practical functionality. Add to that the rigidity and complexity of the control creation model and it’s hard to justify using Microsoft AJAX for anything but the server-side controls provided in UpdatePanel and the AJAX Toolkit controls.
The next topic Rick mentions is the tendency for Web Forms developers to overly mix business and presentation logic. While good separation of concerns can be done using Web Forms, it takes a lot of discipline.
A bigger concern for professional shops is the difficulty in testing. Web Forms simply don't lend themselves well to automated testing. This difficulty partially arises from simulating Context, Request, Response, and Session objects. The rest of the problems come from trying to work around its event-driven model.
MVC completely side steps the issues by throwing away the Page class and its associated baggage. Rick describes it as,
Microsoft implemented MVC as an alternate Http Handler framework so it’s not based on the Page class and bypasses a lot of the complexities of the Web Forms framework. One of the key features is the ability to create custom views that are responsible for rendering output for specific tasks. The controller is responsible for using the model to perform core application processing and then feeding result data to the view to render. It’s quite conceivable to build re-usable views for rendering RSS feeds or other XML output or a specific page display view like a login form or error page for example. By default, however, ASPX pages cane still be used to render a view’s output using a ViewPage class. This class is based on the Page class, but it’s not called directly as an HTTP handler but rather just as a renderer from within the MVC engine which is still much more lightweight than running through the full page framework that a typical ASPX page runs through at runtime.
Some of the controls and techniques from Web Forms can be still be used, but only if they don't rely on post backs. Instead of controls, developers will find themselves using a lot of inline scripting that looks like Classic ASP.
MVC’s model works through URL routing to specific controller methods and any operation routes back to a specific method in the controller. Microsoft based the routing engine on a Ruby-like mechanism that parses clean URLs (like http://localhost/Customers/Show/1) and routes these URLs to specific controllers based on the URL scheme. The routing mechanism – like most things in the MVC framework – can be overridden easily so you can use different URL semantics to route a URL to a controller.
Rick finds some amusement in how things have gone full circle in the last ten years,
It’s interesting to hear this discussion given that Web Forms has been the darling of Web development on the .NET platform. In fact, I find it somewhat ironic to see that MVC is in some ways reverting back to more ASP classic-style ways of working with script-like HTML rendering and raw manual output, but with a much more strictly regimented approach to enforce methodology and code logic. I also remember the early days of ASP.NET when the ASP.NET Nazis were going around disdainfully condemning any use of script tags and inline script or assigning explicit URLs instead of using postbacks, yet some of those same folks undoubtedly are the ones welcoming MVC with open arms now. Ironic, ain’t it?
It’s too early to tell whether MVC will actually address the needs of most Web developers. Certainly from what’s been shown so far it looks like MVC will require a lot more code to build even simple pages. I’ve seen an early build of the framework and it’s not really clear to me how to effectively handle more complex pages without at some point getting mired into huge case statements to route code to decide which portion of the page needs updating. I have built several Web frameworks in the past that use a similar approach to MVC and while you can easily do many simple things, in my experience this approach really starts falling apart when you have pages that contain many different and somewhat independent components. Managing this complexity through a controller-based approach that manages no state for you is much more difficult than what Web Forms provides today. We’ll have to wait and see how the framework shapes up and what patterns emerge to handle more complicated tasks. It probably helps to look at some of the Java or even some of the existing .NET frameworks that have been around for a while for doing MVC based Web development and compare notes.
Rick concludes,
For the moment I’m not quite ready to throw out the baby with the bathwater and put all of my hopes on a new unproven framework. There are a lot of good things going for Web Forms and just because Microsoft has decided to try something new doesn’t mean we all have to jump to it. After all, MVC frameworks have been around for some time and they haven’t made any significant inroads today. MVC will appeal to a specific set of developers immediately—for the rest of us, Microsoft will have to build a kick-ass framework to make it at least comparable in flexibility, extensibility, and usability as Web Forms. There are some interesting times ahead. I’ll be watching with interest…