ASP.NET MVC 3 Extensionless URLs on IIS 6

asp.net, asp.net mvc, code 0 comments suggest edit

A lot has been written about how to get ASP.NET MVC running on IIS 6 with extensionless URLs. Up until now, the story hasn’t been very pretty. When running ASP.NET MVC on ASP.NET 4, it gets a lot easier.

To be fair, the part that makes it easier has nothing to do with ASP.NET MVC 3 and everything to do with a little known new feature of ASP.NET 4 creatively called the ASP.NET 4 Extensionless URL feature. ASP.NET MVC 3 requires ASP.NET 4 so it naturally benefits from this new feature.

If you have a server running IIS 6, ASP.NET 4, and ASP.NET MVC 3 (or even ASP.NET MVC 2. I haven’t tried ASP.NET MVC 1.0), your website should just work with the default extensionless URLs generated by ASP.NET MVC applications. No need to configure wildcard mappings nor *.mvc mappings. In fact, you don’t even need to set RAMMFAR to true. RAMMFAR is our pet name for the runAllManagedModulesForAllRequests setting within the system.webserver setting in web.config. You can feel free to set this to false.

<modules runAllManagedModulesForAllRequests="false"/>

When installing ASP.NET 4, this is enabled by default. So if you have a hosting provider still using IIS 6, but does have ASP.NET 4 installed, then this should work for you, unless…

How does this work?

To be honest, it’s a bit of voodoo magic as far as I can tell and there’s a lot of caveats when it comes to using this feature with IIS 6. There are edge cases where it can cause problems. This is why Thomas Marquardt, the implementor of the feature, wrote a blog post on how to disable ASP.NET 4.0 Extensionless URLs just in case.

In that blog post, he describes the bit of magic that makes this work.

Here’s how the v4.0 ASP.NET extensionless URL features works on IIS 6.  We have an ISAPI Filter named aspnet_filter.dll that appends “/eurl.axd/GUID” to extensionless URLs.  This happens early on in the request processing.  We also have a script mapping so that “*.axd” requests are handled by our ISAPI, aspnet_isapi.dll.  When we append “/eurl.axd/GUID” to extensionless URLs, it causes them to be mapped to our aspnet_isapi.dll, as long as the script map exists as expected.  These requests then enter ASP.NET where we remove “/eurl.axd/GUID” from the URL, that is, we restore the original URL.  The restoration of the original URL happens very early.  Now the URL is extensionless again, and if no further changes are made

He also has a list of conditions that must be true for this feature to work. If any one of them is false, then you’re back to the old extensionfull URLs with IIS 6.

I’m Getting a 403 Forbidden

This is not technically related, but when I tried to test this out to confirm the behavior, I ran into a case where every request was giving me a 403 Forbidden error message. Here’s how I fixed it.

In IIS Manager, I right clicked on the Web Services Extension node and selected the menu option labeled Allow all Web Service extensions for a specific application:

iis6-allowing-extensions

In the resulting dialog, I chose the ASP.NET v4.0.30319 option.

iis6-allow-web-service

To double check that everything was configured correctly, I looked at the properties for my website and ensured that Scripts were enabled.

iis6-home-directory-tab

I also clicked on the Configuration… button and made sure that *.axd was mapped to the proper ASP.NET Isapi dll (aspnet_isapi.dll).

iis6-isapi

iis6-extension-mapping

With all that in place, I was able to run standard ASP.NET MVC web application and make requests for /, /home/about/, etc. without any problems!

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

45 responses

  1. Avatar for Nicholas Piasecki
    Nicholas Piasecki December 22nd, 2010

    It is neat, to be sure, but I wish it had been better advertised -- I lost many hours figuring out why our sites were dishing our 404s after moving from .NET 2 to 4, and it was because that new filter functionality broke ISAPI-based URL rewriters like IIRF (because if installed at the site level, the rewriters would "see" the mangled /eurl.axd URL, which the rewrite rules were not written to expect). There's more discussion about it here:
    stackoverflow.com/.../3327031#3327031
    (Don't meant to a Debbie Downer -- I *love* the initiative to make things simpler, especially since a lot of us are stuck on 2K3 for the time being -- but it really did break a common use case!)

  2. Avatar for Phill
    Phill December 22nd, 2010

    I assume this is not limited to MVC3 and can be done for Web Forms in .Net 4.0?

  3. Avatar for haacked
    haacked December 22nd, 2010

    @Nicholas Hey Debbie! ;) Sorry it broke you. It's probably a case we just hadn't considered when it was turned on by default.
    @Phill Correct. I just tend to focus on ASP.NET MVC scenarios since, well, that's my job. :)

  4. Avatar for Brian
    Brian December 22nd, 2010

    Just installed this on an IIS6 machine and was up and running in no time. My only issue is I have a route which ends in .xml that’s not fully working. If I add .xml so .net handles it then the route loads and I see my auto generated sitemap, but then actual xml files stop being served up.

  5. Avatar for Nova Software
    Nova Software December 22nd, 2010

    Yes, my ASP.NET MVC 3 website works on IIS 6 without extinsion. Thanks very much.

  6. Avatar for Felipe Fujiy
    Felipe Fujiy December 24th, 2010

    The aspnet_filter.dll ISAPI Filter is installed at IIS 7 too?

  7. Avatar for amecam
    amecam January 2nd, 2011

    I tried IIS6 & mvc2 on windows server 2003. It is easy to implement the extentionless url feature. The only problem is that it will eat up much more memory than a normal asp.net web form application. But that is ok since I like MVC.

  8. Avatar for Thanigainathan
    Thanigainathan January 4th, 2011

    Its nice that these kind of thing are taken by defualt in asp.nwt mvc 4. Its really mess when mvc doesn't works in iis 6.
    Thanks for letting us know this.
    Thani

  9. Avatar for Janie
    Janie January 5th, 2011

    Hey

  10. Avatar for Kevin
    Kevin January 5th, 2011

    Phil,
    This is great stuff but I have a question... with this new ability do we still need to do the whole Default.aspx page piece for IIS6 still? I get a directory listing denied when I try without... just curious...
    thanks!
    Kevin

  11. Avatar for haacked
    haacked January 6th, 2011

    No, you shouldn't need Default.aspx for an MVC app with this.

  12. Avatar for Brandon
    Brandon January 20th, 2011

    Make sure you have your site in its own App Pool...This blocked my site until I realized it was still in the Default App Pool...

  13. Avatar for Mike He
    Mike He January 28th, 2011

    @Brandon I believe it should work even if your app in DefaultAppPool.

  14. Avatar for Mike He
    Mike He January 28th, 2011

    I put a little bit attention on the stuff of MVC & IIS 6. And I got a interesting result.
    I deploy ASP.NET MVC 2 project (created in VS2010) to IIS 6 on a WIN2K3 server (only .NET Framework 3.5 installed). The only trick I need to do is set 'Copy Local' attribute of System.Web.Mvc assembly to true and no extra work (wildcard mapping, etc). Then the application runs smoothly.
    Details on this post.
    www.cnblogs.com/...

  15. Avatar for arhsim
    arhsim February 13th, 2011

    Thanks a lot. I have been banging my head over this for quite some time now.

  16. Avatar for Mart&#237;n Mutilva
    Mart&#237;n Mutilva February 14th, 2011

    I had the following problem: one ASP.Net MVC 2 worked fine in IIS 6 with .Net 4 installed and the another gave me the 403 error.
    The difference was the application name (and the directory name): The one that didn't work has dots '.' in its name, e.g. Namespace1.ProjectName.WebMVC.
    Changing it to Namespace1_ProjectName_WebMVC solved the problem

  17. Avatar for Kevin Jensen
    Kevin Jensen February 15th, 2011

    I was able to deploy properly but my app keeps trying to redirect on [Authorize] controllers to /Account/Login even though i'm using windows authentication as stated in my web.config
    Here is my web.config: http://pastie.org/1568510

  18. Avatar for Mike Edenfield
    Mike Edenfield February 24th, 2011

    Is this supposed to also work on IIS 5.1?

  19. Avatar for Kjeld Poulsen
    Kjeld Poulsen March 2nd, 2011

    I tried to host a ASP.NET MVC 3 application as a sub application (virtual directory) where the root was ASP.NET 2.0, using one application pool, while the application it self was using .NET 4.0 in another application pool. I was unable to make this work. As soon as i changed the root application to run .NET 4.0 everything worked as it should.

  20. Avatar for doug dexter
    doug dexter March 9th, 2011

    I've been trying to get an MVC3 application to run on an XP Pro box with IIS6 for a week now, and haven't been able to do so..
    I tried this as well, except for the section regarding Web Services Extension node and i still get the error:
    HTTP 401.3 - Access denied by ACL on resource
    Internet Information Services
    I'm not sure what the security settings on the directory (c:\inetpub\wwwroot\mvc3App) is supposed to be though..
    dd

  21. Avatar for haacked
    haacked March 10th, 2011

    @doug Make sure that IUser_MachineName has access to the directories as well as the ASPNET account.

  22. Avatar for El Octavo Guerrero
    El Octavo Guerrero March 16th, 2011

    There is no ASP.NET v4.0.30319 option in Web Services and I've installed Net 4 (with Visual Studio 2010).
    I get a 403 error.

  23. Avatar for jf
    jf March 23rd, 2011

    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

  24. Avatar for Bret Ferrier
    Bret Ferrier March 25th, 2011

    It looks like this doesn't work with IIS6 if you you are using a Virtual Directory and the Default website is not .Net 4. Is there anyway around this?

  25. Avatar for Rui Zhang
    Rui Zhang April 11th, 2011

    I am doing some tests regarding ASP.NET MVC 3, IIS6, and the results are:
    Default website .Net 2, virtual directory, MVC 3 app: fails, error code: 403
    Default website .Net 4, virtual directory, MVC3 app: passes
    Default website .Net 2, existing .Net 2 app; new website.Net 4, MVC3 app: pass

  26. Avatar for Schnoz
    Schnoz May 8th, 2011

    Any update on the virtual directory issue where the root is running 2.0? My client is getting pretty pissed by now.

  27. Avatar for haacked
    haacked May 8th, 2011

    @Schnoz I don't understand your question. Perhaps contact MS support if your client is getting upset to get a speedy resolution or ask the question on our forums: http://forums.asp.net/1146.aspx

  28. Avatar for Schnoz
    Schnoz May 9th, 2011

    Thanks Phil. I did contact support so hopefully we'll get to the bottom of it. But the question is, as per the comments above, that if the root of the site is set to 2.0, the MVC 3 app is not running. If you switch the root to 4.0, the MCV 3 app runs, but it's creating issues with the existing 2.0 applications. This echoes the comments from @Bret and @Rui above, and the comments on this stackoverlow post: stackoverflow.com/.../mvc-3-deployment-to-iis6

  29. Avatar for Schnoz
    Schnoz May 10th, 2011

    Well, I just got off the phone with support. It turns out that if you still have .NET 2.0 on the root, you still need to configure the Wildcard mapping on the MVC 3 directory. I feel silly now :) Thanks!

  30. Avatar for wiiombouwen
    wiiombouwen May 15th, 2011

    Hi,
    Does this work on the IIS 5.1? Because it doesn't work with IIS6 on my computer ?

  31. Avatar for ldp615
    ldp615 May 28th, 2011

    Help me a lot, Thanks!

  32. Avatar for haacked
    haacked May 29th, 2011

    @wiiombouwen No, I believe it requires IIS 7

  33. Avatar for Vanadiumtech
    Vanadiumtech August 11th, 2011

    I ran into a similar issue with v4.0 ASP.Net extension less URL feature on II6 and found a solution through ISAPI Rewrite Module provider, the does not require turning it off. Theissue and the solution as we experienced it is documented here www.vanadiumtech.com/.../Cause-of-eurlaxd.aspx

  34. Avatar for IraIsBack
    IraIsBack August 16th, 2011

    I run on a curious issue with my MVC3 app on a web site virtual directory of IIS 6. I published it from VS2010 (MSDEPLOY) with a virtual directory path on the destination website(wich i assumed will we created on publish). The folder was created on the iis machine but the app didnt work, i got the http 403 (Forbidden), so i tried everything on the previous and current post with no success, the forbidden page still remained.
    The solution that worked for me was to clear and recreate de virtual directory on the IIS to an existing folder on then machine, then i published my mvc3 app and it "just worked". Seems VS2010 publish created the virtual directory path with a wrong configuration. ENSURE YOUR DESTINATION PUBLISH PATH EXISTS ON IIS BEFORE PUBLISHING FROM VS2010. RECREATE IT IF NECESSARY.

  35. Avatar for DamianR
    DamianR September 1st, 2011

    This didn't work for me. I've been trying to setup a local nuget repository on iis6 win2k3 and after hours of trying all sorts of combinations I still need to browse to Default.aspx manually and the extensionless stuff just doesn't work for me. :(

  36. Avatar for J&#252;rg
    J&#252;rg October 26th, 2011

    !!! GREAT IT WORKS FINE !!!
    !!! THANKS A LOT !!!

  37. Avatar for Gaurav Arora
    Gaurav Arora December 8th, 2011

    @Haack - thanks for wonderful and informative post. I am thinking in aspect when I will make bin deployment of MVC3 on IIS6.0?
    Is there any heck to do the same or its plenty of easy same as with IIS7 or above?

  38. Avatar for Craig Howard
    Craig Howard January 17th, 2012

    I had the same issue on IIS 7.5 and the fix was to set the App Pool to Integrated (instead of Classic)

  39. Avatar for Sutikshan
    Sutikshan April 26th, 2012

    Thanks. By any chance, do you know anyone who has written powershell to apply these changes (is it possible in powershell?)

  40. Avatar for Atul
    Atul June 4th, 2012

    Great Job, it works for me :)

  41. Avatar for James Barrow
    James Barrow June 26th, 2012

    Just for info, I had the same issue but under slightly different circumstances. It was a web forms app that used the minification/optimisation bundles. Trying to hit a url like www.site.com/virtualdirectory/Scripts/js was bringing back nothing.
    Unfortunately everything was set up as above but it didn't work for virtual directory so the only solution was a wildcard mapping which did the trick.

  42. Avatar for Luis
    Luis July 12th, 2012

    I got everything to work on II6 (controller/action urls) but i can't get my apis to work on II6 (api/controller/id). They do work fine on local dev server.

  43. Avatar for Don Morris
    Don Morris August 14th, 2012

    Spot on with changing the application root to 4.0 from 2.0. Works like a champ. Many Thanks for this post and to all that posted comments

  44. Avatar for Rick
    Rick August 16th, 2012

    Yesterday I discover an issue with our development server. All sites that are hosted on that box suddenly stopped working correctly. Pages such as default.aspx would not open unless the exact url was put in- I was getting a 404 error referencing this url: /eurl.axd/ae8672d77d1e42428c96660118d2ccd1/
    After some research, I identifed disabling Extensionless URLs as a workable fix. The question is, why did it sudenly break in the first place? Have any recent Microsoft patches broken this feature?

  45. Avatar for MN
    MN February 21st, 2013

    IIS6, Server 2003

    Problem with isapifilter and redirect websites:
    I have a website configured with a host header of domain.com to redirect to www.domain.com, the target domain is NOT asp.net.

    the isapi filter adds /eurl.axd/guid to the request and the redirect includes the /eurl... and since the target site is not asp.net it returns a 404.

    idealy the aspnet_isapi.dll should be updated to detect a 'redirect only' website and not add the eurl.axd.

    my solution has been to remove the aspnet_isapi filter from the root website and add it manually to the only 2 MVC websites on my server.

    this solution has been working just fine for at least a year thru many security updates and server reboots.

    recently something has changed in the security updates process. it seems after an update the filter is removed from the individual sites and added to the root website, breaking my redirect websites.

    I put together a script to remove the filter from the root and add it back to the sites that need it.