I have an MVC project with a /api folder which contains my Web API controllers. I want the following things:
我有一个带有/api文件夹的MVC项目,其中包含我的Web api控制器。我想要以下的东西:
- My MVC site to serve a custom error page when an error occurs
- 我的MVC站点在发生错误时提供自定义错误页面
- My Web API to serve the default error response (json/xml containing exception and stack trace)
- 我的Web API服务于默认的错误响应(json/xml包含异常和堆栈跟踪)
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:
在web。对于我的MVC站点,我有一个httpErrors节点,并将errorMode设置为“Custom”,以便在404s/500s/etc时可以有漂亮的错误页面。在浏览MVC站点时发生:
<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).
然而,在这种配置下,当出现错误时,API将服务于自定义错误页面,而不是带有异常/堆栈跟踪的json/xml(这是期望的行为)。
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.
是否有一种方法可以将自定义错误配置为只适用于我的MVC站点而不适用于Web API?这个博客说没有(http://blog.kristandyson.com/2012/11/iis-httperrors-aspnet-web-api-fully.html),但我想知道,自从那个博客发表之后,是否还有其他人找到了工作。
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.
我想如果没有的话,我可以为我的Web API项目创建一个单独的项目/程序集。这将允许我分别配置MVC和Web API的httpErrors,但我不希望创建另一个项目,这样我就有了另一个Web。配置来配置。
2 个解决方案
#1
61
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
我以前见过节点,但直到现在才明白这是他们的目的。本文将更详细地介绍IIS/的配置继承模型。NET,我发现它非常有用:http://weblogs.asp.net/jongalloway/10 things-asp-net开发人员-应该-know-about-web-config-继承-重写
#2
1
I have not tested this, but how about writing the code to handle your MVC application errors, like shown here http://thirteendaysaweek.com/2012/09/25/custom-error-page-with-asp-net-mvc-4/ ?
我还没有对此进行测试,但是如何编写代码来处理MVC应用程序错误,如http://thirteendaysaweek.com/2012/09/25/custom-error-page-with-asp-net-mvc-4/所示?
His code show that he is doing this at the application level (Global.asax), but I guess you could just as well trap exceptions at a lower level in the same way, with one method for MVC and another one for Web API.
他的代码显示,他在应用程序级别(Global.asax)中执行这个操作,但是我想您也可以用同样的方法在较低的级别捕获异常,使用一个MVC方法,另一个方法用于Web API。
#1
61
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
我以前见过节点,但直到现在才明白这是他们的目的。本文将更详细地介绍IIS/的配置继承模型。NET,我发现它非常有用:http://weblogs.asp.net/jongalloway/10 things-asp-net开发人员-应该-know-about-web-config-继承-重写
#2
1
I have not tested this, but how about writing the code to handle your MVC application errors, like shown here http://thirteendaysaweek.com/2012/09/25/custom-error-page-with-asp-net-mvc-4/ ?
我还没有对此进行测试,但是如何编写代码来处理MVC应用程序错误,如http://thirteendaysaweek.com/2012/09/25/custom-error-page-with-asp-net-mvc-4/所示?
His code show that he is doing this at the application level (Global.asax), but I guess you could just as well trap exceptions at a lower level in the same way, with one method for MVC and another one for Web API.
他的代码显示,他在应用程序级别(Global.asax)中执行这个操作,但是我想您也可以用同样的方法在较低的级别捕获异常,使用一个MVC方法,另一个方法用于Web API。