ASP.NET Web Forms vs. MonoRail
Castle MonoRail has been getting more press than usual lately due to a recent Scott Hanselman podcast and news coming out of the recent MVP conference about the possibility of Microsoft offering their own Model 2 implementation as part of ASP.NET. Here are links to just some of the interesting discussion so far:
- Competing with the community
- Some more information about Castle, and why we are not 1.0
- Thoughts on MonoRail
- MVP Summit Recapped: Linq for Entities, MonoRail, and Shameless Name Dropping
- Andrew Stopford on Web Forms - comments in particular
- Removing the leaky abstractions from WebForms
JD asked me about my views on ASP.NET Web Forms vs. MonoRail so here goes:
ASP.NET
First of all, I have to say that I agree with the many others who point out that Web Forms is a bit of a “leaky abstraction”. Basically, the Web Forms programming model attempts to simulate stateful “Forms” in a stateless web environment. This approach can lead to several practical problems, most notably:
- Unnecessary plumbing required to create the abstraction. Think View State, Control State, events, postbacks, strange ids etc.
- Consequently, poor performance due to the extra baggage. BTW, if you are using an editable DataGrid and your application isn’t a spreadsheet - please stop :-)
- Loss of control of HTML generated and page weight. Yes, I know about extenders but this is still extra work.
- The model obfuscates the “real” nature of the web: GET, POST, parameters, query strings, Post-Redirect-Get pattern etc.
- Consequently, the average developer finds it harder to debug when there’s a problem: The very complexity introduced to make Mort more productive actually kills him when things (inevitably) go bad.
That said, WebForms is a rich platform and like any technology has it’s own sweet spot. As an example, we recently developed BackgroundMotion, a WebForms application commissioned by Microsoft as an example of how to rapidly build a composite web application using the latest MS toolsets. Over the past few weeks it has served as the centerpiece of our presentations at the recent Microsoft NZ Tech Briefing events. The majority of the build was completed by three developers over a three week period. BackgroundMotion is by no means a “smoke and mirrors” job either. It is a proper layered ASP.NET web app incorporating:
- ASP.NET AJAX
- The Web CAB, ObjectBuilder, MVP and Application Controller
- LINQ to SQL
- A proper Domain Model
- Declarative two-way object data binding
- Validation Block
- Unit tests including mock IContext and IRepository<T> with in-memory database
- Standards compliant, cross-browser HTML
As someone who was an early adopter of RoR and is a contributor to MonoRail, I was reasonably happy with the BackgroundMotion turned out. Yes, it’s not perfect, but some of the newer tools like the Web CAB really promoted a solid architecture. Overall, the toolset we employed allowed us to move pretty fast whilst establishing and building on a maintainable (a.k.a testable) architecture.
MonoRail
MonoRail is RoR inspired web framework the runs on the ASP.NET infrastructure. It’s primary advantage over Web Forms is that it’s MVC implementation encourages a solid architecture by leveraging proven web architectural patterns - basically Front Controller, Application Controller, and Template View. A MonoRail application will have an inherently “good” architecture (which is not to say it can’t be corrupted, but out of the box it’s pretty solid.) An important thing to note is that MonoRail, like RoR, achieves this without shielding the developer from the underlying mechanics of the web. In order to understand the advantages of MonoRail, we need to understand the advantages of the aforementioned foundational patterns.
Front Controller
“A controller that handles all requests for a Web site“
MonoRail implements the Front Controller pattern using a custom HttpHandler. For a given request the handler determines which Application Controller and action to invoke. Some of the advantages of this approach are:
- Separation of URI from actual handler. Spin-offs from this are things like friendly URLs, “routing” etc.
- Ability to plug-in interceptors before/after/around the request. In MonoRail these are called “Filters” and can be used to implement things like authentication, logging and other such “aspects”.
- Ability to do more advanced things like “Dynamic Actions“
Application Controller
“A centralized point for handling screen navigation and the flow of an application”
The “C” part in MVC, controllers in MonoRail can be thought of as Application Controllers. A controller consists of a number of “actions” each of which is the handler for a particular request. An action method may interact with a model and render a view, or may choose to redirect to another action. Such flow decisions are made before any thought is given to rendering anything. This is a key point of difference with Web Forms: The view (page) is in no way concerned with anything apart from how to render itself. As I see it, the main spin-offs from this clean separation are:
- Potential for easier testability of controller logic outside the web context
- Consequently, improved maintainability
- Ability to render different views for the same request (see below).
- Better organization of code into logical groupings
- Ability to do intuitive object data binding (parameters on action methods for example)
- Isolation from HttpContext, and therefore ability to extend it. Think Flash in RoR, MonoRail
Template View
“Renders information into HTML by embedding markers in an HTML page”
MonoRail uses a Template View pattern with pluggable view engines. This pattern results in completely decoupled, “thin” views which is a really good thing. It guarantees almost complete control over the rendered output and means that a single controller can can handle requests based on content type by using different view engines. I think this is something that the RoR guys grokked first after they started noticing DRY violations with respect to rendering different output formats like RSS, JSON, XML etc. This is a lot of what’s behind their recent work around REST and Resources. For example, the request: GET “http://foo.com/member/get/1″ is really a request for a member resource with id=1. It is abstract and should not contain any details about the actual result format desired by the consumer. The consumer instead specifies this using some kind of agreed-upon content-type header or similar. Upon receiving a request, the controller can determine the requested output type and invoke the appropriate view engine to render the response. Separation of the view engine from the request handler is essential to achieve this flexibility.
So what do proponents of Web Forms have to say?
Well, some have commented that Web Form’s “eventing and management of control state” is a feature that counts against MonoRail’s Template View approach. I would disagree and simply point out that these are merely artifacts of Web Forms itself. They do not solve any inherent problem in web development. MonoRail doesn’t have the notion of controls or events, so how can not managing them be a problem? :-)
It must also be noted that MonoRail, in it’s current state, is far from perfect. For example, one of the commonly cited advantages of MonoRail over ASP.NET Web Forms is testability. However, Hammett, Castle’s main man recently had this to say about Controller testability:
“The TestSupport component offered by MonoRail is totally flawed. It is useful for us, as we can use it to test how MonoRail is correctly integrated with the ASP.Net API, but it useless for any enterprise project.”
Other problematic areas include:
- Documentation needs work. It’s open source after all :-)
- May be harder for Morts to grok. Like any sharp tool, it must be wielded carefully.
- Not Microsoft. Therefore harder to sell into the enterprise and harder to support
- Tool support not as strong, primarily with respect to working with views.
As usual, at the end of the day both ASP.NET Web Forms and MonoRail have there place as they are different tools suited to different problems, scales and skill-levels.
Castle ActiveRecord now supports pluralization
Check out the latest trunk while it’s still warm :-) Pluralization adds a little bit more Rails love to Castle ActiveRecord. Formally, if no table name was specified when declaring an Active Record, the table name defaulted to the class name:
[ActiveRecord] public class Octopus {} // inferred table Octopus
Now, by using the new configuration option: pluralizeTableNames, we can tell the framework to infer a pluralized name:
<activerecord pluralizeTableNames="true"> ... </activerecord>
[ActiveRecord] public class Octopus {} // inferred table Octopi


