ASP.NET was a huge shift when it first arrived, not just in terms of the
brand-new .NET multilanguage managed code platform (which was a
landmark in its own right), but in that it sought to close the gap between
stateful, object-oriented Windows Forms development and stateless,
HTML-oriented web development.Microsoft attempted to hide both HTTP (with its intrinsic statelessness) and HTML (which, at the time, was unfamiliar to many developers) by modeling a user interface (UI) as a server-side hierarchy of control objects.
Each control kept track of its own state across requests (using the ViewState facility), automatically rendered itself as HTML when needed, and automatically connected client-side events (e.g., a button click) with the corresponding server-side event handler code. In effect, WebForms is a giant abstraction layer aimed to deliver a classic event-driven GUI over the Web. Developers no longer had to work with a series of independent HTTP requests and responses, as we did with earlier technologies; we could now think in terms of a stateful UI. We could “forget” about the Web, build UIs using a drag-and-drop designer, and imagine that everything happened on the server.
What’s Wrong with Traditional ASP.NET?Traditional ASP.NET was a fine idea, and a thrilling prospect at first, but of course reality turned out to be more complicated. Over the years, realworld use of WebForms uncovered a range of weaknesses:
ViewState: The actual mechanism of maintaining state across requests(ViewState) often results in giant blocks of data being transferred between client and server. It can reach hundreds of kilobytes in many real-world applications, and it goes back and forth with every request, frustrating site visitors with a long wait each time they click a button or try to move to the next page on a grid. ASP.NET AJAX suffers this just as badly,1 even though bandwidth-heavy page updating is one of the main problems that Ajax is supposed to solve.
Page life cycle: The mechanism of connecting client-side events with serverside event handler code, part of the page life cycle, can be extraordinarily complicated and delicate. Few developers have success manipulating the control hierarchy at runtime without getting ViewState errors or finding that some event handlers mysteriously fail to execute.
Limited control over HTML: Server controls render themselves as HTML, but not necessarily the HTML you want. Not only does their HTML often fail to comply with web standards or make good use of CSS, but the system of server controls generates unpredictable and complex ID values, which are hard to access using JavaScript.
False sense of separation of concerns: ASP.NET’s code-behind model provides a means to take application code out of its HTML markup and into a separate code-behind class. This has been widely applauded for separating logic and presentation, but in reality, developers are encouraged to mix presentation code (e.g., manipulating the server-side control tree) with application logic (e.g., manipulating database data) in these same monstrous code-behind classes. Without better separation of concerns, the end result is often fragile and unintelligible.
Untestable: When ASP.NET’s designers first set out their platform, they could not have anticipated that automated testing would become such a mainstream part of software development as it is today. Not surprisingly, the architecture they designed is totally unsuitable for automated testing.
Model-View-Controller ArchitectureASP.NET MVC provides greatly improved separation of concerns thanks to its adoption of MVC architecture. The MVC pattern isn’t new—it dates back to 1978 and the Smalltalk project at Xerox PARC—but it’s gaining enormous popularity today as an architecture for web applications, perhaps because of the following:
- User interaction with an MVC application naturally follows a cycle: the user takes an action, and then in response the application changes its data model and delivers an updated view to the user. And then the cycle repeats. This is a very convenient fit for web applications delivered as a series of HTTP requests and responses.
- Web applications already necessitate combining several technologies (e.g., databases, HTML, and executable code), usually split into a set of tiers or layers, and the patterns that arise naturally map onto the concepts in MVC.
Extensibility
The MVC Framework is built as a series of independent components—satisfying a .NET interface or built on an abstract base class—so you can easily replace the routing system, the view engine, the controller factory, or any other framework component, with a different one of your own implementation. In fact, the framework’s designers set out to give you three options for each MVC Framework component:
1. Use the default implementation of the component as it stands (which should be enough for most applications).
2. Derive a subclass of the default implementation to tweak its behavior.
3. Replace the component entirely with a new implementation of the interface or abstract base class.
TestabilityMVC architecture gives you a great start in making your application maintainable and testable, because you will naturally separate different application concerns into different, independent software pieces. Yet the ASP.NET MVC designers didn’t stop there. They took the framework’s component-oriented design and made sure each separate piece was ideally structured for automated testing.
Tight Control over HTMLThe MVC Framework recognizes the importance of producing clean, standards-compliant markup. Its built-in HTML helper methods do of course produce XHTML-compliant output, but there’s a bigger change of mindset at work. Instead of spewing out huge swathes of barely readable HTML code to represent what should be simple UI elements like lists, tables, or string literals, the MVC Framework encourages you to craft simple, elegant markup styled with CSS.
Powerful New Routing SystemToday’s web developers recognize the importance of using clean URLs. It isn’t good for business to use incomprehensible URLs like /App_v2/User/Page.aspx?action=show%20prop&prop_id=82742—it’s far more professional to use /to-rent/chicago/2303-silver-street.
Comparisons with ASP.NET WebForms- WebForms takes the view that UIs should be stateful, and to that end adds a sophisticated abstraction layer on top of HTTP and HTML, using ViewState and postbacks to create the effect of statefulness. This makes it suitable for drag-and-drop Windows Forms–style development, in which you pull UI widgets onto a canvas and fill in code for their event handlers.
- MVC embraces HTTP’s true stateless nature, working with it rather than fighting against it. It requires you to understand how web applications actually work; but given that understanding, it provides a simple, powerful, and modern approach to writing web applications with tidy code that’s easy to test and maintain over time, free of bizarre complications and painful limitations.