I have an MVC project with a /api folder which contains my Web API controllers. I want the following things:
In the web.config for my MVC site, I have an httpErrors node, and have set the errorMode to "Custom" so that I can have nice error pages when 404s/500s/etc. occur during browsing of the MVC site:
<httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" subStatusCode="-1" /> <remove statusCode="500" subStatusCode="-1" /> <remove statusCode="403" subStatusCode="-1" /> <error prefixLanguageFilePath="" statusCode="404" path="Content\notfound.htm" responseMode="File" /> <error statusCode="500" path="/Errors" responseMode="ExecuteURL" /> <error statusCode="403" path="/Errors/Http403" responseMode="ExecuteURL" /></httpErrors>
With that configuration however, the API will serve the custom error page when an error occurs, not json/xml with the exception/stack trace (which is the desired behavior).
Is there a way to configure custom errors to only apply to my MVC site and not the Web API? This blog says there is not (http://blog.kristandyson.com/2012/11/iis-httperrors-aspnet-web-api-fully.html), but I'd like to hear if anyone else has found a work around since that blog was published.
I suppose if there is not I could create a separate project/assembly for my Web API project. That would allow me to configure httpErrors for MVC and Web API separately, but I would prefer not to create another project just so I have yet another web.config to configure.
Well, after a nearly a year of letting this question marinade, I gave it another shot. Here's the web.config magic that got me what I wanted:
<!-- inside of <configuration> to allow error responses from requests to /api through --> <location path="api"> <system.webServer> <validation validateIntegratedModeConfiguration="false" /> <httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough" > <clear/> </httpErrors> </system.webServer> </location> <!-- original httpErrors, inside of <location path="." inheritInChildApplications="false"> to serve custom error pages when the MVC site returns an error code --> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="400" subStatusCode="-1" /> <remove statusCode="404" subStatusCode="-1" /> <remove statusCode="500" subStatusCode="-1" /> <remove statusCode="403" subStatusCode="-1" /> <error statusCode="400" prefixLanguageFilePath="" path="Content\notfound.htm" responseMode="File"/> <error prefixLanguageFilePath="" statusCode="404" path="Content\notfound.htm" responseMode="File" /> <error statusCode="500" path="/errors" responseMode="ExecuteURL" /> <error statusCode="403" path="/errors/http403" responseMode="ExecuteURL" /> </httpErrors>
The crux of what's going on here is that the <location>
node allows you to override settings made at a less specific path. So while we have errorMode="Custom" for path=".", we override that for the our Web API's path with the <location path="api">
node, and the httpErrors configuration within it.
I had seen nodes before, but it didn't dawn on me that this was their purpose until now. This article goes into more detail on the configuration inheritance model of IIS/.NET, which I found very informative: http://weblogs.asp.net/jongalloway/10-things-asp-net-developers-should-know-about-web-config-inheritance-and-overrides
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With