I’m going to do a series of short posts summarising the core architectural structure of ASP.NET MVC. This is really for my own benefit – to make sure I understand it in detail – so if someone else has already covered these topics, it doesn’t matter!
This first component isn’t strictly part of the MVC framework. It was created by the MVC team, and is built to support it, but it actually operates completely independently and could be used as a standalone URL rewriting mechanism for any ASP.NET application. The objective is to catch nice URLs like
/Products/Beans/Page7 and invoke an appropriate IHttpHandler with parameters extracted from the URL.
Registering with IIS
Before Routing can do anything, it needs ASP.NET to be registered with IIS to handle the incoming requests. There are three methods:
|Use .mvc extension on all URLs, and register that extension to be handled by ASP.NET||IIS 5.1+|
|Wildcard URL mapping||IIS 6.0+|
|Set runAllManagedModulesForAllRequests="true" on system.webServer/modules||IIS 7.0|
Using either of the last two methods means that IIS will invoke ASP.NET to handle all your requests. Unfortunately, for IIS5.1 (XP), you need the .mvc in the URL as wildcard mapping isn’t supported (see end of post for workaround).
Intercepting the ASP.NET pipeline
When you create a new MVC web application, you’ll get this line added to your web.config:
<httpmodules> <add type="System.Web.Mvc.UrlRoutingModule, etc etc... " name="UrlRoutingModule" /> </httpmodules>
|UrlRewritingModule is the core component in Routing. When it’s invoked during the processing of a request, it does the following before ASP.NET runs any IHttpHandler:
Cast and crew
RouteData- holds a Route, plus a list of the values matched to its placeholders
IRouteHandler – is an IHttpHandler factory
MvcRouteHandler – is an IRouteHandler that always supplies an MvcHandler instance
That’s it! Notice that there’s no mention of controllers or actions or whatnot, because as I said, routing is completely separate from MVC. All the MVC-specific responsibilities are held by MvcHandler, which will be the starting point for the next post in this series.
Suggested extensions and tweaks
- Use extensionless URLs with IIS5.1. Don’t like that dirty .mvc in your URL? Use ISAPI Rewrite (freeware version) to forward all requests to /blah.ashx, then put in your own IHttpModule (before UrlRewritingModule) to rewrite back to the original URL (hint: it’s stored in the header X-Rewrite-Url). Handy if you’re developing on XP.
- Try writing your own URL matching logic. If you don’t like MVC’s Route syntax, want to write your own that uses Regexes, want the configuration to come from a database or whatever, well, bad luck! You can’t change any behaviour of Route, because we have neither an interface or any virtual methods on Route. Your only option is to replace the entirety of UrlRoutingModule, but even then you’re stuck because the HtmlHelper methods are hard-coded to call System.Web.Mvc.RouteTable. Perhaps this might be opened up a bit in a future release (Phil Haack hinted as much in a blog comment).
- Handle part of the URL space outside MVC – perhaps you want to serve static content on some URLs really quickly. Make an IHttpHandler to serve the content, and an IRouteHandler to instantiate the handler. Use this type as the RouteHandler in one of your Route registrations.