是否可以使用带有MVC站点而不是Web API的自定义错误页面?

时间:2022-11-24 11:12:44

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.

这里的关键是 节点允许您覆盖在一个不太特定的路径上所做的设置。因此,while我们有errorMode="Custom" for path="。,我们使用 节点,以及其中的httpErrors配置来覆盖Web API的路径。

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.

这里的关键是 节点允许您覆盖在一个不太特定的路径上所做的设置。因此,while我们有errorMode="Custom" for path="。,我们使用 节点,以及其中的httpErrors配置来覆盖Web API的路径。

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。