Using ASP.NET 4.0 Extension-less Routing on IIS 7.5

Routing in ASP.NET 4.0 is a great way to set up friendly URLs with minimal effort. The process of doing this has been well described in many articles (see references below). Routing in ASP.NET 4 supports extension-less URLs, so that you can set up a mapping like this:

http://www.mydomain.com/Products/Beverages

instead of the version that has to add .aspx (or another extension mapped to managed modules):

http://www.mydomain.com/Products/Beverages.aspx

However, some developers have discovered that while this works with no additional configuration on the ASP.NET Development Server, on IIS 7.5, this does not work out-of-the-box.

The Cause

The cause of the problem is related to when a managed module is invoked on an incoming request. Managed modules (vs. Native modules) are only executed for requests to that map to managed handlers. That of course includes requests for URLs with the .aspx extension and several more. However, URLs with no extension are not mapped to a managed handler and thus the managed module that takes care of the URL Routing is not invoked.

The Solutions

There are three solutions, two are commonly discussed in forums, but aren’t the best option out there. I’ll review those first and discuss why they are not such a good choice. Finally, I will discuss the third solution, which solves the problem without impacting performance or other modules.

Note: technically, there is another solution, which is to use the URL Rewrite modules for IIS 7.5. However, that requires the routes to be set up by the web server administrator instead of the developer.

1. Modify web.config to Run All Managed Modules for All Requests

One (brute-force) way to fix the problem is to add an attribute to your application’s web.config (or even to the server’s configuration) that indicates that all managed modules should be run for all incoming requests, regardless of what type of handler they map to.

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

This is a very indiscriminate way of solving the problem. It causes (as the attribute name implies) all managed modules to run for all requests. Normally, managed modules only run for requests that involve managed handlers. (The opposite of a managed handler is a native handler.) There is a performance penalty for invoking modules, so invoking many managed modules for a request, let’s say, for a CSS or JPG file is not exactly wise.

2. Modify the UrlRoutingModule-4.0 preCondition

There is a way in which you can modify web.config to indicate that the UrlRoutingModule-4.0 should run on all requests, even those for non-managed handlers. The solution is similar to number one, but instead of running all managed modules on all requests, only the URL Routing Module will run on all requests.

If you look at the web server’s configuration (in IIS Manager), you will find that a checkbox is checked in the configuration for the UrlRoutingModule-4.0 entry:

URL Routing Module Properties

Unchecking that box will cause the UrlRoutingModule-4.0 (and only that module, other managed modules are not affected) to be run for all requests. This applies to all sites on your server. As an alternative, you can modify your web.config to include the following lines:

<system.webServer>
  <modules>
    <remove name="UrlRoutingModule-4.0" />
    <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
  </modules>
</system.webServer>

If you already have a modules section, you would just add lines 3 and 4.

Just like solution number one, this still affects requests for static files, such as style sheets and images. It’s a better solution than number one, because at least not all managed modules are invoked. A system with no extensions installed has 14 managed modules (out of a total of 30). All would be executed in the first solution. So there is an improvement, but it’s still not perfect.

3. Apply the Official Microsoft Hotfix

Now, the real cause of the problem actually has to do with an incorrect interpretation of handler mappings when the handler mapping is set to “*.”. So, yes, it’s a bug in IIS.

Microsoft has released a hotfix for this issue and you can find information about it and download the hotfix from http://support.microsoft.com/kb/980368.

Applying the hotfix does not require any of the above solutions.

References

Farr, C. (2010, June 4). Don’t use runAllManagedModulesForAllRequests=”true” when getting your MVC routing to work. Retrieved January 25, 2011, from British Developer: http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html

Gildner Solutions. (2010, April 21). ASP.NET 4.0 URL routing 404 problems with IIS7. Retrieved January 25, 2011, from Gildner Solutions: http://www.gildnersolutions.com/post/2010/04/21/ASPNET-40-URL-problem-with-IIS7.aspx

Guthrie, S. (2007, February 26). Tip/Trick: Url Rewriting with ASP.NET. Retrieved January 25, 2011, from The Official Microsoft ASP.NET Site: http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx

Microsoft Corporation. (2010, April 27). A update is available that enables certain IIS 7.0 or IIS 7.5 handlers to handle requests whose URLs do not end with a period. Retrieved January 25, 2011, from Micorosoft Support: http://support.microsoft.com/kb/980368

Advertisements

3 thoughts on “Using ASP.NET 4.0 Extension-less Routing on IIS 7.5

  1. Thanks Sven. Bacon saved.

    A very welcome pool of informed advice on an interweb increasingly full of bad baseless opinions!

    For testing purposes I’ve been deploying a MVC ASP.Net website to IIS running on a Windows Server 2008 SP2 box and this little piece of history bit me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s