The MVC routing assembly – part V
Today we’re going to talk about one of the most important components of the System.Web.Routing assembly: the UrlRouting module. If you want to use the routing framework in your web applications, then you need to register this module on your web.config file (of course, after adding a reference to the routing assembly in your web app). This means that you’ll need to do register the module on your web.config file:
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
The place where you put the previous line depends on the version of IIS you’re using. If you’re using IIS 6, then you’ll need to put it inside the system.web/httpModules section. On the other hand, if you’re using IIS 7, then just put it inside the system.webServer/modules section.
Now that you’ve set up your app to use the routing module, lets see what it does. Currently, the module handles two application events: the PostResolveRequestCache and the PostMapRequestHandler events. Most of the work is done on the PostResolveRequestCache. During that event, the module will use the RouteTable (more info about this object can be found on my previous post) object to get a route that matches the current request’s url.
When that happens, the module receives a valid RouteData instance (ie, a non-null RouteData instance). This object has all the necessary info about the current route.The most important info is (arguably) the IRouteHandler instance that will be responsible for getting the HTTP handler that will return a response to the client. Interestingly, the routing assembly introduces only one IRouteHandler type: the StopRoutingHandler.
Whenever the module encounters a StopRoutingHandler, it knows it should simply do…nothing. On the other hand, if it finds a non-StopRoutingHandler, it will start by creating a new RequestContext (fed with the current HTTP context and with the previously obtained RouteData instance). Then it will get the HTTP handler responsible for processing the request by calling the IRouteHandler.GetHttpHandler method.
Finally, the module ends up creating a new RequestData instance (used for storing the current request’s url and HTTP handler) and putting it on the Items collection (available on the current HTTP context).
During the PostMapRequestHandler event, the module tries to recover the RequestData previously stored. If it finds it, then it will use the HTTP handler presented on the RequestData to set up the Handler property of the current HTTP context.
And that’s it! As you can see, the module doesn’t really do anything fancy. Most of the work depends on getting a valid route that matches the current request. I believe that its’s fair to say that getting a match is more interesting than the work that is done after finding a route. So, on the next post, we’ll talk about the matching algorythm used internally to see if the current url matches any of the pre-registered routes. Keep tuned.