4

I have an ASP.NET MVC 4 application running under IIS 8.5. My previous understanding/experience of these scenarios in MVC is that if a static file exists, it will be served. If it doesn't exist, the path will be sent through MVC routing. This is the desired behaviour, but doesn't seem to be happening.

By default if I create a catchall route at /blah.html and no corresponding static file, IIS serves up a 404 (courtesy of the StaticFile handler). The MVC route is never hit. If the file exists, it is served.

So, I did some Googling and chatting to colleagues and came up with the answer as posted here:

https://stackoverflow.com/a/14327897/1043198

In goes the handler:

<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />

Great! The request now hits the MVC app and my dynamic content is served as expected. Except now, when I put a physical file in place, I get an error again. An uninformative 500 error with the following information (and nothing else):

Module: ManagedPipelineHandler

Notification: ExecuteRequestHandler

Handler: ApiURIs-ISAPI-Integrated-4.0

Error Code: 0x800703e9

What's going on? Why does IIS not fall back to my MVC app when static files don't exist and how come when I fix that, the inverse occurs and static files are no longer served properly? I'm fairly sure this has always been default behaviour in the past.

App pool is running in Integrated mode, CLR v4.0.

Community
  • 1
  • 1
Ant P
  • 24,820
  • 5
  • 68
  • 105

1 Answers1

3

After finding various answers and blog posts suggesting enabling runAllManagedModulesForAllRequests, it seems that this - while it works - isn't the right approach.

RAMMFAR does exactly what it says on the tin and runs all requests (including those for "unmanaged" static resources) through all managed modules, which has a performance overhead and can also cause unusual side-effects depending on the modules enabled and the requests run through them.

Turns out the only module required to solve this problem is the UrlRoutingModule which, when the precondition is removed, causes all static resources to be run through MVC routing (when no static file exists):

<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule"   
    preCondition="" />
Ant P
  • 24,820
  • 5
  • 68
  • 105
  • @JotaBe I will, in two days. – Ant P Jan 24 '14 at 16:24
  • This fixes it but its not the correct answer. Becasue using a satic path tells IIS to treat the path like a route, ignoring any mime types. THis answers tells ISS to pass everything to the application regardless of mime type and if that fails fall back to IIS. WHich might degrade performance if there allot of unmanaged calls to static files. – Piotr Kula Feb 24 '14 at 13:51
  • @ppumkin You're right - have been meaning to update this answer. – Ant P Feb 24 '14 at 13:56
  • Yea thats great... but I found this because of the stupid 500 error. Locally it works fine but on live server it just shows IIS 500, not the application 500. It doesn't get logged or show any reasons for error. SO i might have to use RAMMFAR after all... or if you know why? Ill try the UrlRouting one though :) – Piotr Kula Feb 24 '14 at 13:59
  • Down-voting because it's unclear from the comments whether this is a good answer. – Dave Watts Apr 23 '14 at 13:18
  • @AntP - From comments 3 and 4 I inferred that the answer was incorrect. A more assertive 'I've updated the answer' on Feb 24 at 13:56 would have done the trick. Yep, I can see now on closer inspection that the answer edit and the 4th comment were made at the same time. If you want to tweak the answer I'll remove my downvote. – Dave Watts Apr 28 '14 at 11:37
  • I am not sure why this is still receiving downvotes given that it is the single correct solution to this problem. I would advise that anyone encountering this issue ignore the downvotes. – Ant P Oct 08 '14 at 18:06