Link here

Link here

Mindset shifts between ASP.NET and MVC/Rails (and the future of web development…)

Uncategorized 6 Comments »

Let’s imagine your web development team is going to move out of “classic” ASP.NET and into MonoRail/ASP.NET MVC/etc. We assume you have a good reason (”It’s new and exciting” is usually good enough for us devs).

What kind of issues are you going to face? What questions are going to keep coming up?

“… but how do I do postbacks?”

The loss of the postback model is going to hit a lot of web developers hard - there’s a big mindset shift to make. So how did we get here, and where are we going?

In the history of web development so far, there have basically been two major different approaches/philosophies to web UI.

1. Event-driven

Just like with native GUI apps, we imagine that when the user clicks a button, we can change the text on some label. When they change a value in a list, the “total” is updated. The fact that this stateful UI has to be transmitted over HTTP is just a technical obstacle to be overcome.

2. RESTful

Following the principles of REST and SOA, we understand that the cleanest web apps are stateless. We think in terms of requests and responses, working with HTTP rather than against it.

While RESTful apps are the fashion today, don’t forget that it’s the older technology. In 1997, the age of Perl, we had no choice. The first Event-driven platforms came later, achieving their statefulness through complicated abstraction layers (ASP.NET), fiddly scripting (AJAX), or abandoning HTML entirely (Flash).

Here’s another way of comparing the two mindsets:

Event-driven RESTful
ASP.NET RoR, MonoRail, ASP.NET MVC
Stateful Stateless
Heavyweight Lightweight
Overcomes HTTP Embraces HTTP
Widgets HTML
3rd-party controls DIY
Design view Code view
GUI Web page
Postbacks -
Partial page updates* Full page updates
Web 1.0 (uncool) Web 2.0 (cool)

* I know classic ASP.NET actually replaces the whole page on a postback, but the mental model is that it’s doing partial page updates. It just technically uses full page updates to achieve that.

Note I’m trying to keep AJAX out of this, because it’s just a way of strapping extra event-driven semantics on top of whatever other platform you’re using. I totally accept that it’s useful today, but in 3-5 years it will be gone and we won’t miss it.

So which should I use?

Another way to think about the progression of these approaches is like this:

  RESTful Event-driven
Ineffective web technology Perl, Plain PHP ASP.NET
Effective web technology RoR, MonoRail, (ASP.NET MVC?) ?

The most effective web frameworks today are undoubtedly the highly-streamlined, designed-for-HTTP, MVC derivatives. I call ASP.NET “ineffective” because anyone who’s used it for more than a few years knows that the abstraction doesn’t really work, it tends to be too heavyweight, and the “page lifecycle” is the software equivalent of cholera.

What’s the future?

The future is not Ruby on Rails. It’s not ASP.NET MVC either, though that will hopefully improve our industry for the next 2-4 years and you should probably use it.

The future is, inevitably, obviously, undoubtedly, the question mark on the table above. It has to be an event-driven architecture since that matches both the end-user and developer’s instincts about UIs. But unlike ASP.NET, it will be thick-client, not a load of leaky abstractions. It may be so well integrated into the OS that users don’t think of it as being different to their local apps.

In other words, the future is client-side. Well, it’s going to be interesting anyway.

In depth: The ASP.NET MVC Pipeline

ASP.NET, MVC 11 Comments »

If what we’ve heard is true, then the new ASP.NET MVC framework will be the most customisable and extensible web development platform Microsoft has ever shipped.

If you want to take advantage of that, or if you’re just trying to make sense of what bit does what, you’ll want to open up the bonnet and check out the engine.

The Pipeline

ASP.NET MVC Pipeline Thumbnail

Disclaimer: this information is based on pre-CTP1 code samples, so it might be outdated or just plain wrong. I will update this post and the diagram when the public CTP is shipped.

Download diagram: PDF, JPEG

0. App initialisation

When the application starts up, like any ASP.NET application, it runs Global.asax’s Application_Start() method.

In this method, you can add Route objects to the static RouteTable.Routes collection (which is of type RouteCollection). These will be inspected later when each request is received. Each Route object defines a URL pattern to be matched and the controller to be used in this case. Optionally, you can specify a controller action and a custom IRouteHandler if you don’t want to use the default (which is MvcRouteHandler).

If you’re implementing a custom IControllerFactory (for example, if you’re using a 3rd-party Inversion of Control container, like Castle Windsor), you can set this as the active controller factory by assigning it to the System.Web.Mvc.ControllerFactory.Instance property.

1. Routing

Overview: Routing is a stand-alone component that matches incoming requests to IHttpHandlers by URL pattern. MvcHandler is, itself, an IHttpHandler, which acts as a kind of proxy to other IHttpHandlers configured in the Routes table.

The combination of System.Web.Mvc.MvcHandler and System.Web.Mvc.UrlRoutingModule references in the web.config give responsibility for handling all incoming requests to MvcHandler.

First, MvcHandler calls Routes.GetRouteData() which matches the incoming request against the list of Route objects added in Application_Start(). The appropriate Route is chosen and a RouteData object prepared. This references the appropriate IRouteHandler and IController to be used.

Next, the IRouteHandler’s GetHttpHandler() is called, returning an IHttpHandler, whose ProcessRequest() method is finally invoked. The default IHttpHandler as returned by MvcRouteHandler is, again, MvcHandler, which performs steps 2-4 below.

ScottGu offers another view of this routing process.

2. Instantiate and execute controller

Overview: The active IControllerFactory supplies an IController instance

MvcHandler’s ProcessRequest() method calls ControllerFactory.Instance.CreateController(), passing context information including the type of controller obtained in the RouteData object previously.

The active IControllerFactory is responsible for instantiating and returning an appropriate IController. Usually, this will be a subclass of the Controller base class.

The IController’s Execute() method is then called. If this is a subclass of Controller, steps 3 and 4 below are performed.

3. Locate and invoke controller action

Overview: The controller invokes its relevant action method, which after further processing, calls RenderView()

The Controller.Execute() method uses the RouteData and other context information to pick the appropriate action method. This method must have a [ControllerAction] attribute to be eligible for selection. It also maps incoming request parameters (querystring, form etc from the IHttpRequest context object) to the parameter list of the action method.

The controller calls its own InvokeAction() method, passing details of the chosen action method, which, predictably, invokes the action method. This is where your code finally runs.

Within your [ControllerAction] method, you’re expected to call the Controller’s RenderView() method. By this time, you will have populated the controller’s ViewData property. RenderView() performs step 4 below.

4. Instantiate and render view

Overview: The IViewFactory supplies an IView, which pushes response data to the IHttpResponse object.

The view subsystem follows the same factory pattern as routing. That is, the Controller object has a property called ViewFactory which is of type IViewFactory. The IViewFactory interface defines a method called CreateView(), which takes a view name and other context information, using which it instantiates and returns an IView.

The controller can now invoke the IView’s RenderView() method, supplying the necessary context information, which includes ViewData and the IHttpResponse object to which it can push any text or binary data into the response. This response data may be HTML, an image, or any other binary or text data.

Summary / Conclusion

As a developer working with ASP.NET, you won’t need to worry about the intricacies of IRouteHandler and IViewFactory and the like very often. The typical development process is simply:

  • From Global.asax, add a Route object representing a certain URL pattern you want to catch and map to a controller / action
  • Add a Controller subclass, whose [ControllerActions] should be invoked in response to requests, populating ViewData
  • Add a view template that uses ViewData to render some HTML

The thing to remember is that there are many extensibility points all over the framework, so if you want to build a custom view engine or a custom request routing system, you can hook in at the appropriate points. Hopefully the diagram and explanation above will prove useful if you’re just starting to do that.

kick it on DotNetKicks.com

Site Meter