July 2009

Volume 24 Number 07

Cutting Edge - Comparing Web Forms And ASP.NET MVC

By Dino Esposito | July 2009

Contents

Benefits of ASP.NET Web Forms
Drawbacks of Web Forms
Benefits of ASP.NET MVC
Drawbacks of ASP.NET MVC
The Right Perspective
What's the Perfect Model for ASP.NET?
Undisputable Facts
At the End of the Day

I first saw Microsoft ASP.NET in action in 1999, when it was tentatively named ASP+. At that time, building a Web application on the Microsoft platform was a matter of assembling a bunch of Active Server Pages (ASP).

In a typical ASP page, you find HTML literals interspersed with code blocks. In code blocks, script code (mostly VBScript) is used to incorporate data generated by COM objects, such as components from the ActiveX Data Objects (ADO) framework. Undoubtedly, the introduction of ASP.NET in the late 1990s was a big step forward, as it represented a smart way to automate the production of HTML displayed in a client's browser.

ASP.NET simplified a number of everyday tasks and, more importantly, enabled developers to work at a higher level of abstraction.This allowed them to focus more on the core functions of the Web application rather than on common tasks around Web page design.

Based on server controls, ASP.NET allows developers to build real-world Web sites and applications with minimal HTML and JavaScript skills. The whole point of ASP.NET is productivity, achieved through powerful tools integrated in the runtime as well as the provision of development facilities, such as server controls, user controls, postback events, viewstate, forms authentication, and intrinsic objects. The model behind ASP.NET is called Web Forms and it was clearly inspired by the desktop Windows Forms model (in turn deeply inspired by the Visual Basic Rapid Application Development philosophy).

So why did Microsoft release "another" ASP.NET framework, called ASP.NET MVC? In this article, I'll explore the pros and cons of both ASP.NET Web Forms and ASP.NET MVC.

Benefits of ASP.NET Web Forms

As noted, ASP.NET Web Forms is stable and mature, and it is supported by heaps of third party controls and tools.

One of the keys to the rapid adoption of ASP.NET is certainly the point-and-click metaphor taken from Windows desktop development. With Web Forms, Microsoft basically extended the Visual Basic programming model to the Web. Desktop development, however, is stateful whereas the Web is inherently stateless. So the Web Forms model essentially abstracted a number of features to provide a simulated stateful model for Web developers. As a result, you didn't have to be a Web expert with a lot of HTML and JavaScript knowledgeto write effective Web applications.

To simulate stateful programming over the Web, ASP.NET Web Forms introduced features such as viewstate, postbacks, and an overall event-driven paradigm.For example, the developer can, say, double-click on a button to automatically generate a stub of code that will handle the user's clicking to the server. To get started writing an ASP.NET Web application, you just need to know the basics of .NET development, the programming interface of some ad hoc components, like server controls. Server controls that generate HTML programmatically, and the runtime pipeline, contribute significantly to a fast development cycle.

At the end of the day, key features of ASP.NET Web Forms are just the componentization of some ASP best practices. For example, postback, auto-population of input fields, authentication and authorization before page rendering, server controls, and compilation of the page, are not features devised and created from scratch for ASP.NET Web Forms. All of them evolved from ASP best practices. Ten years ago, ASP developers (including myself) were looking for exactly the set of features that Web Forms ended up providing. Furthermore, ASP.NET Web Forms generally exceeded our expectations by providing a full abstraction layer atop the whole Web stack: JavaScript, CSS, HTML.

To write an ASP page, you did need to know quite a bit about the Web and script languages. To write an ASP.NET page, in contrast, you need to know primarily about .NET and its compiled languages. Productivity and rapid development of data-driven, line-of-business applications have been the selling points of ASP.NET Web Forms. Until now, that is.

Drawbacks of Web Forms

Like many other things in this imperfect world, ASP.NET Web Forms is not free of issues. Years of experience prove beyond any reasonable doubt that separation of concerns (SoC) has not been a natural fit with the Web Forms paradigm.

Automated testing of an ASP.NET Web Forms application is hard, and not just because of a lack of SoC. ASP.NET Web Forms is based on a monolithic runtime environment that can be extended, to some extent, but it is not a pluggable and flexible system. It's nearly impossible to test an ASP.NET application without spinning up the whole runtime.

To achieve statefulness, the last known state of each server page is stored within the client page as a hidden field—the viewstate. Though viewstate has too often been held up as an example of what's wrong with Web Forms, it is not the monster it's made out to be. In fact, using a viewstate-like structure in classic ASP was a cutting-edge solution. From an ASP perspective, simulation of statefulness (that is, postback, viewstate, controls) was a great achievement, and the same was also said at first about how Web Forms isolated itself from HTML and JavaScript details.

For modern Web pages, abstraction from HTML is a serious issue as it hinders accessibility, browser compatibility, and integration with popular JavaScript frameworks like jQuery, Dojo, and PrototypeJS. The postback model that defaults each page to post to itself, makes it harder for search engines to rank ASP.NET pages high. Search engines and spiders work better with links with parameters, better if rationalized to human-readable strings. The postback model goes in the opposite direction. Also, an excessively large viewstate is problematic because the keyword the rank is based on may be located past the viewstate, and therefore far from the top of the document. Some engines recognize a lower rank in this case.

Benefits of ASP.NET MVC

Some of the recognized issues with the Web Forms model can be fixed within ASP.NET 4.0. You can disable or control the size of the viewstate. (Even though very few developers seem to have noticed, the size of the viewstate decreased significantly in the transition from ASP.NET 1.1 to ASP.NET 2.0 when Microsoft introduced a much more efficient serialization algorithm. In ASP.NET 4.0, you should also expect improvements in the way in which viewstate can be disabled and controlled.) You can use an ad hoc HTTP module to do URL rewriting or, better yet, you can use the newest Web routing API from ASP.NET 3.5 SP1. In ASP.NET 4.0, you can minutely control the ID of elements, including scoped elements. Likewise, in ASP.NET 4.0 the integration of external JavaScript frameworks will be simpler and more effective. Finally, the history management API in ASP.NET 3.5 SP1 made AJAX and postback work together while producing a search-engine-friendly page.

In many aspects, the Web Forms model in ASP.NET 4.0 is a better environment that tackles some of the aforementioned flaws. So what's the point of ASP.NET MVC?

You'll find a good introduction to ASP.NET MVC in the March 2008 issue MSDN Magazine ("Building Web Apps without Web Forms"), where Chris Tavares explains the basics of ASP.NET development without Web Forms. In summary, ASP.NET MVC is a completely new framework for building ASP.NET applications, designed from the ground up with SoC and testability in mind. When you write an ASP.NET MVC application, you think in terms of controllers and views. You make your decisions about how to pass data to the view and how to expose your middle tier to the controllers. The controller chooses which view to display based on the requested URL and pertinent data. Each request is resolved by invoking a method on a controller class. No postbacks are ever required to service a user request. No viewstate is ever required to persist the state of the page. No arraysof black-box server controls exist to produce the HTML for the browser.

With ASP.NET MVC, you rediscover the good old taste of the Web—stateless behavior, full control over every single bit of HTML, total script and CSS freedom.

The HTML served to the browser is generated by a separate, and replaceable, engine. There's no dependency on ASPX physical server files. ASPX files may still be part of your project, but they now serve as plain HTML templates, along with their code-behind classes. The default view engine is based on the Web Forms rendering engine, but you can use other pluggable engines such as nVelocity or XSLT. (For more details, have a look at the MVCContrib Web site at mvccontrib.codeplex.com.)

The runtime environment is largely the same as in ASP.NET Web Forms, but the request cycle is simpler and more direct. An essential part of the Web Forms model, the page lifecycle, is no longer necessary in ASP.NET MVC. It should be noted, though, that the default view engine in ASP.NET MVC is still based on the Web Forms rendering engine. This is the trick that allows you to use master pages and some server controls in ASP.NET MVC views. As long as the view engine is based on Web Forms, the view is an ASPX file with a regular code-behind class where you can handle classic events such as Init, Load, PreRender, plus control-specific events such as RowDataBound for a GridView control. If you switch off the default view engine, you no longer need Page_Loador other events of the standard page lifecycle. Figure 1 compares the run-time stack for Web Forms and ASP.NET MVC.

Figure 1

Figure 1 The Run-Time Stack at a Glance (Click the image for a larger view)

It should be noted that the "Page lifecycle" boxes in Figure 1 have been collapsed for readability and include several additional events each. Anyway, the run-time stack of ASP.NET MVC is simpler and the difference is due to the lack of a page lifecycle. However, this makes it problematic to maintain the state of visual elements across page requests. State can be stored into Session or Cache, but this decision is left to the developer.

Figure 2 illustrates the sequence of an ASP.NET MVC request.

Figure 2

Figure 2 The Sequence Diagram of an ASP.NET MVC Request (Click the image for a larger view)

The MVC acronym stands for Model-View-Controller. However, you should note that the pattern depicted in Figure 2 doesn't exactly match the classic formulation of the MVC pattern. In particular, in the original MVC paper, Model and View are tied together through an Observer relationship. The MVC pattern, though, is deliberately loosely defined and, even more importantly, was devised when the Web was still to come. Adapting MVC to the Web moved it toward the model in Figure 2, which is also known as Model2. In general, when you talk or read about MVC be aware that there are quite a few slightly different flavors of it within the literature.

Drawbacks of ASP.NET MVC

So ASP.NET MVC brings to the table a clean design with a neat separation of concerns, a leaner run-time stack, full control over HTML, an unparalleled level of extensibility, and a working environment that enables, not penalizes, test-driven development (TDD). Is ASP.NET MVC, therefore, a paradise for Web developers?

Just like with Web Forms, what some perceive as a clear strength of ASP.NET MVC, others may see as a weakness. For example, full control over HTML, JavaScript, and CSS, ASP.NET MVC means that you enter the Web elements manually. Much of this pain can be mitigated, however, with some of the more recent JavaScript libraries and even different view engine. In general, though, there's no sort of component model to help you with the generation of HTML, as there is in the Web Forms approach. Currently, HTML helpers and user controls are the only tools you can leverage to write HTML more quickly. As a result, , some ASP.NET developers may see ASP.NET MVC as taking a step backward in terms of usability and productivity. Another point to be made, regarding the impact of ASP.NET MVC on everyday development, is that it requires some upfront familiarity with the MVC pattern. You need to know how controllers and views work together in the ASP.NET implementation. In other words, ASP.NET MVC is not something you can easily learn by experimenting. In my experience, this may be the source of decreased productivity for the average Web Forms developer.

The Right Perspective

As an architect or developer, it is essential that you understand the structural differences between the frameworks so that you can make a thoughtful decision. All in all, ASP.NET Web Forms and ASP.NET MVC are functionally equivalent in the sense that a skilled team can successfully use either to build any Web solution.

The skills, education, and attitude of the team, though, are the key points to bear in mind. As you may have figured out yourself, most of the features presented as a plus for either framework may also be seen as a minus, and vice versa. Full control over HTML, for example, may be a lifesaver to one person but a nightmare to another. Personally, I was shocked the first time I saw the content of a nontrivial view page in ASP.NET MVC. But when I showed the same page to a customer whose application was still using a significant number of ASP pages, well, he was relieved. If you have accessibility as a strict requirement, you probably want to take full control over the HTML being displayed. And this is not entirely possible with Web Forms. On the other hand, if you're building a heavy data-driven application, you'll welcome the set of data-bound controls and statefulness offered by Web Forms.

Correctly, Microsoft has not positioned ASP.NET MVC as a replacement for ASP.NET Web Forms. Web Forms is definitely a pattern that works for Web applications. At the same time, Ruby-on-Rails has proved that MVC can also be a successful pattern for Web applications; and ASP.NET MVC confirms this.

In the end, Web Forms and ASP.NET MVC have pros, cons, and structural differences that affect various levels. Generalizing, I'd say that Web Forms embraces the RAD philosophy whereas ASP.NET MVC is TDD-oriented. Further, Web Forms goes toward an abstraction of the Web that simulates a stateful environment, while ASP.NET MVC leverages the natural statelessness of the Web and guides you towards building applications that are loosely coupled and inherently testable, search-engine friendly, and with full control of HTML.

What's the Perfect Model for ASP.NET?

After using Web Forms for years, I recognize a number of its drawbacks, and ASP.NET MVC addresses them quite well: testability, HTML control, and separation of concerns. But though I see ASP.NET MVC as an equally valid option at this time, I don't believe it to be the silver bullet for every Web application. In my opinion, ASP.NET MVC today lacks some level of abstraction for creating standard pieces of HTML. HTML helpers are just an interesting attempt to speed up HTML creation. I hope to see in the near future a new generation of MVC-specific server controls, as easy and quick to learn and use as Web Forms server controls, but totally unbound from the postback and viewstate model. My hopes are for a System.Web.Mvc.GridView control that saves me from writing a loop to generate an HTML table, while offering column templates, server-side data-binding events, and styling options. What would be the difference between such an MVC GridView and today's Web Forms GridView? The MVC GridView would only emit HTML plus, optionally, some row-specific JavaScript, but it wouldn't manage things like paging and sorting. Paging and sorting will be delegated to other specific controls or plain links created by the developer. In this way, the MVC GridView could bring some RAD flavor to ASP.NET MVC, speeding up the development of pages without precluding handcrafted pages.

Going back to the root of the problem, the key difference between Web Forms and ASP.NET MVC is the underlying pattern. Web Forms is a model based on the "Page Controller" pattern. Web Forms are UI-focused and centered around the concept of a page: the page gets input, posts back, and determines the output for the browser. The development environment was therefore devised to enable rapid prototyping, via wizards and rich designers. Any user action ends up in a method on the code-behind class of each page. At that point, though, nothing prevents you from using proper SoC and nothing really stops architects from imposing patterns like MVC, Model-View-Presenter (MVP) or even Model-View-View-Model (MVVM).

The Web Forms architecture does not encourage SoC, but it doesn't prevent it either. The Web Forms architecture makes it seductive to opt for drag-and-drop of controls, to code logic right in event stubs without further separation, and to drop data sources right on the page, which couples the UI directly to the database. MVC is neither prohibited nor a blasphemy in Web Forms; it's just that very few developers practice it because it requires working around much of the Web Forms infrastructure.

Testability is a different story. ASP.NET Web Forms doesn't prevent unit testing, but it requires much disciple and repetitive boilerplate coding to do so.As long as you code your way to SoC you can test and reuse presentation and business logic. Sure, you likely don't have the Visual Studio project template to create a test project for you. You need to become familiar with testing and mocking frameworks and manage those projects yourself. But this can be done. From a testability perspective, though, a real difference exists between Web Forms and ASP.NET MVC. In Web Forms, you just don't have the flexibility of ASP.NET MVC. This is a true limitation. ASP.NET MVC is designed with testability in mind,which means that the framework architecture guides the developer to write code that is inherently testable, that is isolated from the context or connected to it via contracted interfaces. Even more importantly, in ASP.NET MVC intrinsic objects are mockable as they expose interface and base classes. From a testing standpoint, the best you can do in Web Forms is to move your logic into separate and easily testable classes. Then, you test the presentation (ASPX and code-behind) by sending HTTP requests and checking the results. You can't do this in Web Forms without spinning up the whole ASP.NET runtime, however. In ASP.NET MVC, the majority of testing is to assure that the data being passed into the view is correct. In addition, you can mock up intrinsic objects and run your tests in a genuinely isolated environment.

We should also note that control over HTML and SEO-friendly URLs, both advantages of ASP.NET MVC, can be achieved to some extent in Web Forms. ASP.NET 3.5 SP1, in particular, includes the URL Routing and History API for SEO. CSS adapters, instead, are the tools to leverage to try to control HTML in Web Forms. Integration with JavaScript and AJAX frameworks is, frankly, no longer an issue in Web Forms.

Undisputable Facts

ASP.NET Web Forms and ASP.NET MVC are not competitors in the sense that one is supposed to replace the other. You have to choose one, but different applications may force you to make different choices. In the end, it's really like choosing between a car and a motorcycle when making a trip. Each trip requires a choice, and having both vehicles available should be seen as an opportunity, not as a curse. Here are some facts about the frameworks:

  • Web Forms is hard to test.
  • ASP.NET MVC requires you to manage the generation of HTML at a more detailed level.
  • ASP.NET MVC is not the only way to get SoC in ASP.NET.
  • Web Forms allows you to learn as you go.
  • Viewstate can be controlled or disabled.
  • Web Forms was designed to abstract the Web machinery.
  • ASP.NET MVC exposes Web architecture.
  • ASP.NET MVC was designed with testability and Dependency Injection in mind.
  • ASP.NET MVC takes you towards a better design of the code.
  • ASP.NET MVC is young and lacks a component model.
  • ASP.NET MVC is not anti-Web Forms.

ASP.NET MVC was not created to replace Web Forms but to partner it. ASP.NET MVC turns some of the weaker elements of Web Forms into its own internal strengths. However, problems such as lack of testability, SoC, SEO, and HTML control can be avoided or reduced in Web Forms with some discipline and good design, though the framework itself doesn't provide enough guidance.

At the End of the Day

We have seen that there are pros and cons in both Web Forms and ASP.NET MVC. Many developers, however, seem to favor ASP.NET MVC because it represents the only way to get SoC and testability into their applications. Is it really the only way? No. However, ASP.NET MVC makes it easier and natural to achieve SoC and write more testable code. ASP.NET MVC doesn't magically transform every developer into an expert architect and doesn't prevent developers from writing bloated and poorly designed code. At the end of the day, both Web Forms and ASP.NET MVC help to build applications that are designed and implemented to deal effectively with the complexity of real-world solutions. No software magic exists, and none is yet supported by the ASP.NET platform.

Send your questions and comments for Dino to cutting@microsoft.com.

Dino Esposito is an architect at IDesign and the co-author of Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Based in Italy, Dino is a frequent speaker at industry events worldwide.