find a location for property in a new city

Friday, 4 June 2010

Don't use runAllManagedModulesForAllRequests="true" when getting your MVC routing to work

It seems to be common advice to make your modules section of your web.config say <modules runAllManagedModulesForAllRequests="true">. In fact this is quite a drastic thing to do to solve the routing problem and has global effects that could CAUSE ERRORS.

You need a module that goes by the name of UrlRoutingModule-4.0 to be running through IIS. Now, since your MVC URLs are likely to end without .aspx these will not be picked up by IIS and run through the intergrated pipeline and therefore you will end up with 404 not found errors. I struggled with this when I was getting started until I found the <modules runAllManagedModulesForAllRequests="true"> workaround.

This highly recommended fix can cause other problems. These problems come in the form of making all your registered HTTP modules run on every request, not just managed requests (e.g. .aspx). This means modules will run on ever .jpg .gif .css .html .pdf etc.

This is:
  1. a waste of resources if this wasn't the intended use of your other modules
  2. a potential for errors from new unexpected behaviour.

Better solution

Fine, so the ranting about <modules runAllManagedModulesForAllRequests="true"> is over. What is a better solution?

In the modules section of your web.config, you can add the UrlRoutingModule-4.0 module in with a blank precondition meaning it will run on all requests. You will probably need to remove it first since it is most likely already registered at machine level. So make your web.config look like this:
<modules>
  <remove name="UrlRoutingModule-4.0" />
  <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
  <!-- any other modules you want to run in MVC e.g. FormsAuthentication, Roles etc. -->
</modules>

Note: the modules element does NOT contain the runAllManagedModulesForAllRequests="true" attribute because it is evil!

Follow britishdev on Twitter

26 comments:

  1. Thank you! I've been fighting this issue for several days, and now have it working correctly.

    ReplyDelete
  2. Phil Hartmann1 July 2010 18:26

    even better solution

    http://support.microsoft.com/kb/980368

    ReplyDelete
    Replies
    1. that worked for me! need to sing that link out from the rooftops, have been pulling my hair out for hours

      Delete
    2. Same here. No need to specify modules manually if you install the hotfix.

      Delete
    3. awesome ..i was struggling with this from few days...

      Delete
    4. awesome ..i was struggling with this from few days...

      Delete
  3. Hi!

    Removing the runAllManagedModulesForAllRequests="true" flag or setting it to false has one pitfall: Some of the global.asax event handlers stop working for MVC requests.

    With your configuration in a new MVC application project Application_Start and Application_End events are no problem, but Application_BeginRequest, Application_EndRequest, Session_Start etc. are firing for an added ~/Test.aspx, but not for ~/Home/Index which is an MVC controller and action. As soon as I add the runAllManagedModulesForAllRequests="true" flag all event handlers are firing for MVC actions too.

    ReplyDelete
  4. Thanks for your comment. Although, please note line 4 in my code: <!-- any other modules you want to run in MVC e.g. FormsAuthentication, Roles etc. -->

    It is true that some modules will not be fired on MVC pages without the runAllManagedModulesForAllRequests="true" but this is why those modules should be added into added into the modules section (with preCondition="").

    Setting runAllManagedModulesForAllRequests="true" will run ALL modules under the sun in EVERY request under the sun (e.g. css files). Using runAllManagedModulesForAllRequests="true" is a kind of brute false 'just make it work' code thats stinks and I believe should be avoided. In my case it was also causing errors.

    I agree with what you are saying I just believe that not using that property is best if you can

    ReplyDelete
  5. I don't understand the comment in line 4.

    Are you saying that any module you want to run in MVC need to be after the UrlRoutingModule line in web.config, or are you saying that they need to also set preCondition="" and deal with getting called on every request?

    I THINK that you're saying that they need preCondition=""?

    ReplyDelete
  6. Correct. I wasn't suggesting an order, I was saying the modules needed in MVC will need preCondition=""

    ReplyDelete
  7. Some Application events does not get invoked in Global.asax after I set runAllManagedModulesForAllRequests to false. For example this one:
    Application_AuthorizeRequest.

    I've added these modules to web.config:

    ReplyDelete
    Replies
    1. Can you give an example of how to add these modules to web.config for events in global.asax that don't fire anymore?

      Delete
  8. Thanks for the useful info!

    ReplyDelete
  9. Hi,

    Could you explain why on 20 windows boxes that are identical to each other in every way possible, our MVC application gives 404 errors on 3 of them unless we add "runAllManagedModules=true" to the web.config?

    We've spent an entire day trying to figure this out.

    ReplyDelete
  10. Have you checked your root config files. I.e. machine.config and web.config (the root web.config - the one that is in the same place as the machine.config not the one in the web application)

    ReplyDelete
  11. Hi, I am recently just trying what you suggest and I have added the module to the web.config and machine.config files of my framework folder.

    I have also added them too my web.config in my solution.

    I still get the same messages, I have restarted my pc several times to ensure it was not an issue with that.

    Thanks!

    ReplyDelete
  12. Thank you so much - this solved my problem - I spent about 6 hours trying to fix this! Yay!

    ReplyDelete
  13. was very helpful thanks

    ReplyDelete
  14. Or you could try this Microsoft Hotfix - http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=5272

    extensionless URLs worked fine on our dev IIS 7.5 server without needing anything at all in the modules section, but didn't work on our live server. After installing the above hotfix, they 'just worked' on the live server as well.

    ReplyDelete
  15. hi experts,
    I am facing a very strange problem. If I use,





    My all session variables & Forms Authentications User Identity stopped working. I am getting "Object reference not set to an instance of an object." error if I use session variables & authentication Identity.
    But If I use "", my problem solved.

    Any idea ??

    ReplyDelete
    Replies
    1. Hi,, Anuj.. I m facing the error.. did u manage to find the solution?

      Thanks in Advance.


      Regards,
      Vani

      Delete
  16. One thing to note - this method wasn't firing the EndRequest event on my project (.Net 4). This caused us a lot of bother due to some 'tidy up' stuff that was happening once the request had gone.

    Ended up putting a handler mapping in for XML instead (in system.webserver > handlers):





    Cheers,

    Paul

    ReplyDelete
  17. Thank You, I've been pulling my hairs out for ours too :)

    ReplyDelete
  18. This comment has been removed by the author.

    ReplyDelete
  19. Adding the specific module needed worked for us. We had the "evil" runAllManagedModulesForAllRequests="true" attribute, but didn't want to use it because of the performance concerns (and should you just run all really?). Simply adding the correct module, and removing that evil attribute solved the problem.




    ReplyDelete