Charteris Community Server

Welcome to the Charteris plc Community
Welcome to Charteris Community Server Sign in | Join | Help
in Search

gopalk

How does ASP.NET MVC work?

If you’ve looked at the ASP.NET MVC framework, you might have wondered how it fits within the rest of the ASP.NET lifecycle. To understand it though, the ASP.NET request lifecycle needs to be understood first.

What happens when an ASP.NET request is made?

The answer depends on the version of IIS being used. In IIS 5.0 / 6.0, ASP.NET support was accomplished using an isapi extension i.e. aspnet_isapi.dll. In IIS 5.0 / 6.0 there is a distinct handover of the request from IIS to .NET before any managed code can respond to the request. This is achieved by mapping certain extensions like .aspx, .asmx etc to aspnet_isapi.dll extension by using application mapping within IIS manager interface.

But in IIS 7.0 (running in integrated mode) things are different. IIS 7.0 integrates the ASP.NET runtime with the core web server and there is no specific handoff needed from IIS to ASP.NET. Thus for a managed HttpModule to execute, the request doesn’t have to be routed to ASP.NET first. A managed HttpModule can be added via IIS manager itself and can be made to execute for both managed and native requests. Similarly a managed HttpHandler class can be mapped to specific extensions directly via IIS manager (which stores the configuration in applicationHost.config file.) or via the web application’s web.config file.

So what happens when a request gets through to ASP.NET?

1. ApplicationManager and HostingEnvironment classes are created. ApplicationManager class manages Applications and their AppDomain for all the applications on the hosting process. ApplicationManager can be used to do cool things like hosting ASP.NET in your custom process, see here: http://www.west-wind.com/WebLog/posts/4976.aspx . This is also the stage when any necessary compilation of code in App_Code folder occurs.

2. HttpRequest, HttpResponse and HttpContext objects are created and populated. At the end of this stage these objects are usable.

3. Now the current HttpContext is assigned to an instance of HttpApplication (or instance of Global.asax if exists). At the same time any HttpModules (inherited from parent app or defined in web.config) are initialised. The HttpApplication class defines a set of stages/events that get executed one by one and carry the processing forward in distinct steps. Note that the HttpModules that have been initialised will attach themselves to one or more of these lifecycle events defined on HttpApplication instance.

4. HttpApplication lifecycle events fire in succession:

Note that the list of lifecycle events on HttpApplication is extensive and the objective here is not to analyse the entire lifecycle, so I’ll skip the parts that are not directly relevant for this exercise. For an extensive look at HttpApplication lifecycle elements look here:

IIS7: http://msdn.microsoft.com/en-us/library/bb470252.aspx

IIS5/6: http://msdn.microsoft.com/en-us/library/ms178473.aspx

The first relevant event in the HttpApplication lifecycle that we need to look at is MapRequestHandler. Now this step is new in .NET 3.5 but an equivalent step (without the corresponding event) existed before .NET 3.5. It is in this step that an HttpApplication selects an HttpHandler to service the request. Now the selection of HttpHandler will be based on web.config or inherited configuration. The HandlerFactory set in the configuration will be used to acquire an instance of the Handler which is then assigned to the context.

So for example, if a request is for an ‘aspx’ file, in the MapRequestHandler stage, HttpApplication will map ‘.aspx’ request to PageHandlerFactory. GetHandler method is then invoked on PageHandlerFactory which returns an instance of the appropriate Page class (Page is basically an HttpHandler and implements IHttpHandler interface). This is then attached to the Handler property of the context class.

Let’s skip a few more steps and go to the ProcessRequest stage. By now the request (To be precise the HttpContext object encapsulating the request.) already has an HttpHandler assigned to it as seen earlier. The request is now processed here by invoking the ProcessRequest method on the HttpHandler.

Wasn’t this about MVC?

In MVC, there is no concept of a Page as in a traditional webform page, i.e. the web page requested doesn’t exist on the disk as a file. Instead it’s served up by a special method (‘the Action’) on a special class (‘the Controller’). This is quite a dynamic routing arrangement as it needs to respond to varying URL’s. And if you do not want to use a special extension (like .mvc) for these MVC requests, then you can’t really use an HttpHandler entry in web.config/IIS. (There does exist a handler for .mvc in web.config if you want to use .mvc extension for your MVC requests.)

So, how does ASP.NET know how to route requests to MVC? The answer lies in web.config. There is a new http module added to modules collection in ASP.NET MVC projects

<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />

This was originally a part of MVC framework but since has been released as a separate assembly. The other part in this routing magic is played by Global.asax RegisterRoutes method.

routes.MapRoute("Default", "{controller}/{action}/{id}",new { controller = "Home", action = "Index", id = "" });

MapRoute is an extension method on RouteCollection class that can be used to define possible routes. In the background this method sets the routes you define to be handled by MvcRouteHandler class.

The UrlRoutingModule attaches itself to PostResolveRequestCache and PostMapRequestHandler events of the HttpApplication instance and overrides the default behaviour of MapRequestHandler stage. UrlRoutingModule does this by searching the RouteCollection for a route matching the request. If it’s found, the associated RouteHandler is retrieved from the RouteCollection. In our case this is an MvcRouteHandler instance. An instance of MvcHandler is retrieved from MvcRouteHandler and assigned as the handler for the current context. Nice thing to note is that RouteCollection is one of the points where the MVC framework can be extended. This can be done by defining a custom RouteHandler corresponding to the routes (instead of the MvcRouteHandler). There is some good information here on how to this.

http://msmvps.com/blogs/luisabreu/archive/2008/07/23/the-mvc-framework-the-mvcroutehandler.aspx

As a side note, also note that UrlRoutingModule will by default ignore any requests that match a file that exists on the disk. Thus if a request for WebForm1.aspx is received and it happens to exist on the disk then route lookup will be skipped for this request. This behaviour can be changed (at your own peril!) by setting routes.RouteExistingFiles = true ;

Now there might be a case where a custom handler needs to be defined within our MVC web application (For integrating third party products/user controls). This may not exist on the disk and will trigger a route table lookup and a 404 if no matching routes are found. To avoid this, RouteCollection can be instructed to ignore this specific path in the following way.

routes.IgnoreRoute("<your route>");

So in this post we saw how a request was routed from IIS through to the MVC framework and along the way, an extensibility point was identified. From here it needs to be routed through to the right action on the right controller class, but that could be the topic of an entirely new post!

Published Jan 20 2009, 06:56 AM by gopalk
Filed under: , ,

Comments

 

Reflective Perspective - Chris Alcock » The Morning Brew #269 said:

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #269

January 21, 2009 8:25 AM
 

Newly Noted #8 | Patrick Verbruggen's Blog said:

Pingback from  Newly Noted #8 | Patrick Verbruggen's Blog

January 21, 2009 8:05 PM
 

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout

January 22, 2009 3:36 AM
 

La Web de Programación said:

Ronda de noticias, y descargas añadidas a la sección correspondiente : Windows Live Calendar sale de

January 23, 2009 8:34 AM
 

links for 2009-01-27 « pabloidz said:

Pingback from  links for 2009-01-27 &laquo; pabloidz

January 27, 2009 12:03 PM
 

ASP.NET MVC Archived Buzz, Page 1 said:

Pingback from  ASP.NET MVC Archived Buzz, Page 1

February 9, 2009 12:45 AM
 

gopalk said:

In the last post we saw how an ASP.NET MVC request gets routed through to the MVC framework through the

February 11, 2009 7:43 AM
 

Tagz | "How does ASP.NET MVC work? - gopalk" | Comments said:

Pingback from  Tagz | &quot;How does ASP.NET MVC work? - gopalk&quot; | Comments

May 16, 2009 5:56 PM

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Commercial Edition), by Telligent Systems