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.
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="" />
User contributions licensed under CC BY-SA 3.0