哪些HTTP状态码用于MVC错误处理

时间:2021-04-20 00:19:45

I'm currently developing custom error pages in my error handling code for my MVC application. But I'm unclear as to which HTTP status codes I'm meant to cover.

我目前正在为我的MVC应用程序开发错误处理代码中的自定义错误页面。但是我不清楚我要包含哪些HTTP状态码。

Question: is there a typical list of HTTP status codes that should be catered for?

问:是否有一个典型的HTTP状态码列表需要满足?

Alot articles which explain how to do MVC error handling and custom error pages but appear to only show several of the HTTP Status Codes: 403, 404, and 500 in their error handling code. What about HTTP Status Code: 408 as an example? Should this be covered? What about the tonne of other status codes - HTTP status codes on wiki

很多文章解释了如何进行MVC错误处理和自定义错误页面,但似乎只显示了几个HTTP状态码:403、404和500。HTTP状态码:408是一个例子吗?这应该覆盖吗?那么其他的状态码呢——在wiki上的HTTP状态码

This may sound like a dumb question, but I really don't know the answer and can't find an information on this. Am I missing something here, i.e. should only a subset of status codes be covered?

这听起来可能是个愚蠢的问题,但我真的不知道答案,也找不到相关的信息。我是否遗漏了一些东西,例如,是否应该只覆盖状态码的子集?

If it helps, below is what I've done for my MVC error handling. This code (so far with the little testing that I've done) covers 404, and all 50x type exceptions:

如果有帮助的话,下面是我对MVC错误处理所做的工作。这段代码(到目前为止我所做的小测试)包含404,以及所有50x类型的异常:

1 In web.config, and entry for each HTTP status code I want to cover

1在web。配置,以及我要介绍的每个HTTP状态代码的条目

<httpErrors errorMode="Custom" existingResponse="Replace" >
  <remove statusCode="403" />
  <remove statusCode="404" />
  <remove statusCode="500" />
  <error statusCode="403" responseMode="ExecuteURL" path="/Error/Forbidden" />
  <error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
  <error statusCode="500" responseMode="ExecuteURL" path="/Error" />
</httpErrors>  

2 An error controller

2一个错误控制器

    namespace MyApp.Controllers
    {
      public class ErrorController : Controller
      {
      public ActionResult Index()
      {
        return View();
      }
      public ActionResult Forbidden()
      {
        return View();
      }
      public ActionResult NotFound()
      {
        return View();
      }

3 User friendly error pages:

3用户友好错误页面:

/Views/Shared/Index.cshtml
/Views/Shared/Forbidden.cshtml
/Views/Shared/NotFound.cshtml

4 ELMAH for logging

4 ELMAH日志

Further findings at 2 Nov 2015

2015年11月2日的进一步发现

Something I've just discovered that has been staring me in the face which I've missed... In IIS, the default Error pages covered are:

我刚刚发现的一些东西一直盯着我的脸,我已经错过了……在IIS中,所涵盖的默认错误页面有:

  • 401 – Unauthorized
  • 401 -未经授权
  • 403 – Forbidden
  • 403年被禁止的
  • 404 – Not Found
  • 404 -未找到
  • 405 – Method Not Allowed
  • 405 -方法不允许
  • 406 – Not Acceptable
  • 406 -不能接受的
  • 412 – Precondition Failed
  • 412 -失败的前提
  • 500 – Internal Server Error
  • 内部服务器错误
  • 501 – Not Implemented
  • 501 -未实现
  • 502 – Bad Gateway
  • 502 -错误网关

If this is good range Microsoft have set, then I will go by this as a guide going forwards!

如果这是微软已经设定好的范围,那么我将以此作为前进的指南!

4 个解决方案

#1


2  

An interesting question, IMHO.

一个有趣的问题,恕我直言。

These three errors (403, 404 and 500) are the most common errors that can happen to the real user accessing your site with a standard browser.

这三个错误(403、404和500)是真正使用标准浏览器访问站点的用户最常见的错误。

On other hand, the HTTP standard was written for both server and agent developers in order to define how both sides should operate. Naturally, the standard browsers like IE, Chrome, Firefox, etc. as well as the standard robots like Google or Bing bots correctly fulfill the requirements, but some proprietary written agent may send a malformed request, and the standard provides the set of codes the server should send in this situation. For example, if the Content-Length field is missed the server returns the error code 411. However, you shouldn't provide user-friendly pages for such a situation.

另一方面,HTTP标准是为服务器和代理开发人员编写的,目的是定义双方应该如何操作。当然,IE、Chrome、Firefox等标准浏览器以及谷歌或Bing bots等标准机器人能够正确地满足需求,但一些专有的书面代理可能会发送错误的请求,标准提供了服务器在这种情况下应该发送的一组代码。例如,如果错过了Content-Length字段,服务器将返回错误代码411。但是,您不应该为这种情况提供用户友好的页面。

The code 408 (Request timeout) is explained in the standard as following:

代码408(请求超时)在标准中解释如下:

"The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."

在服务器准备等待的时间内,客户端没有发出请求。客户可以在以后的任何时候重复请求而不做任何修改。”

and it also not a case you should make user-friendly page for.

这也不是一个你应该做用户友好页面的情况。

To make a long story short, don't worry :)

长话短说,别担心:

#2


3  

There may be another way: this solution uses 1 custom-error page to handle all types (I think?)

可能还有其他的方法:这个解决方案使用一个自定义错误页面来处理所有类型(我认为?)

[1]: Remove all 'customErrors' & 'httpErrors' from Web.config

[1]:从Web.config中删除所有“自定义错误”和“httpErrors”。

[2]: Check 'App_Start/FilterConfig.cs' looks like this:

[2]:检查FilterConfig App_Start /。cs的看起来像这样:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

[3]: in 'Global.asax' add this method:

[3]:在“全球。asax”添加这个方法:

public void Application_Error(Object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    var routeData = new RouteData();
    routeData.Values.Add("controller", "ErrorPage");
    routeData.Values.Add("action", "Error");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    Response.TrySkipIisCustomErrors = true;
    IController controller = new ErrorPageController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();
}

[4]: Add 'Controllers/ErrorPageController.cs'

[4]:添加“控制器/ ErrorPageController.cs”

public class ErrorPageController : Controller
{
    public ActionResult Error(int statusCode, Exception exception)
    {
         Response.StatusCode = statusCode;
         ViewBag.StatusCode = statusCode + " Error";
         return View();
    }
}

[5]: in 'Views/Shared/Error.cshtml'

[5]:在“视图/共享/ Error.cshtml”

@model System.Web.Mvc.HandleErrorInfo
@{
    ViewBag.Title = (!String.IsNullOrEmpty(ViewBag.StatusCode)) ? ViewBag.StatusCode : "500 Error";
}

<h1 class="error">@(!String.IsNullOrEmpty(ViewBag.StatusCode) ? ViewBag.StatusCode : "500 Error"):</h1>

//@Model.ActionName
//@Model.ContollerName
//@Model.Exception.Message
//@Model.Exception.StackTrace

#3


2  

I'm trying to find out the answer also. My code looks scarily like yours. This is a great question with so few views, I've set a bounty on this question. I myself have handled the following codes so far:

我也想找出答案。我的代码看起来像你的一样。这是一个很好的问题,几乎没有什么观点,我已经对这个问题下了定论。到目前为止,我自己已经处理了以下代码:

<system.webServer>
  <!-- Custom error pages -->
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <!-- Redirect IIS 400 Bad Request responses to the error controllers bad request action. -->
    <remove statusCode="400" />
    <error statusCode="400" responseMode="ExecuteURL" path="/error/badrequest" />
    <!-- Redirect IIS 401 Unauthorized responses to the error controllers unauthorized action. -->
    <remove statusCode="401" />
    <error statusCode="401" responseMode="ExecuteURL" path="/error/unauthorized" />
    <!-- Redirect IIS 403.14 Forbidden responses to the error controllers not found action. 
         A 403.14 happens when navigating to an empty folder like /Content and directory browsing is turned off
         See http://rehansaeed.co.uk/securing-the-aspnet-mvc-web-config/ and http://www.troyhunt.com/2014/09/solving-tyranny-of-http-403-responses.html -->
    <error statusCode="403" subStatusCode="14" responseMode="ExecuteURL" path="/error/notfound" />
    <!-- Redirect IIS 404 Not Found responses to the error controllers not found action. -->
    <remove statusCode="404" />
    <error statusCode="404" responseMode="ExecuteURL" path="/error/notfound" />
    <!-- Redirect IIS 500 Internal Server Error responses to the error controllers internal server error action. -->
    <remove statusCode="500" />
    <error statusCode="500" responseMode="ExecuteURL" path="/error" />
  </httpErrors>
</system.webServer>

My reasoning is as follows:

我的推理如下:

  • 400 - Controllers have the BadRequest() method built in and you may want to return this when a parameter passed to the action is invalid.
  • 400 -控制器内置了BadRequest()方法,当传递给操作的参数无效时,您可能希望返回这个方法。
  • 401 - Applying the Authorize attribute to a controller or action causes a 401 Unauthorized response. Controllers also have the Unauthorized() method built in.
  • 向控制器或操作应用授权属性会导致401未授权响应。控制器中还内置了未授权的()方法。
  • 403.14 - Redirect these to 404 Not Found responses as a Forbidden is just plain wrong (See Securing your web.config and Troy Hunt's blog for more information).
  • 403.14 -将它们重定向到404未找到的响应作为禁止是完全错误的(参见保护您的web。config和Troy Hunt的博客获取更多信息)。
  • 404 - Thrown when the user browses to a page not found.
  • 404 -当用户浏览未找到的页面时抛出。
  • 500 - Thrown when something goes catastrophically wrong.
  • 500 -当发生灾难性的错误时抛出。

Overall I feel you should handle those codes that you yourself are going to use. The problem is that IIS does all kinds of strange things and we need to handle some of it's incorrect or invalid responses such as the 403.14 I listed above.

总的来说,我觉得你应该处理你自己将要使用的那些代码。问题是IIS会做各种奇怪的事情,我们需要处理一些不正确或无效的响应,如我上面列出的403.14。

Here is a complete list of IIS HTTP Status Codes and Sub-Status Codes which might be useful to our cause. I have a feeling the 403 Forbidden response should also be supported as it seems to be a fairly prominent response thrown by IIS.

下面是IIS HTTP状态码和子状态码的完整列表,它们可能对我们的目标有用。我有一种感觉,403的禁止响应也应该得到支持,因为它似乎是由IIS抛出的一个相当突出的响应。

One interesting thing I discovered while Googling is that navigating to:

我在谷歌上发现的一件有趣的事情是:

yoursite/<script></script>

Returns a 500 Internal Server from IIS. I feel this should return a 404. The IIS error page does not tell us what the Sub-Status Code is and I would be interested to know how we can find out, so that we can redirect the 500.Something to a 404 Not Found page.

从IIS返回一个500个内部服务器。我觉得应该返回404。IIS错误页面没有告诉我们子状态代码是什么,我很想知道如何查找,以便我们可以重定向500。404页面未找到。

Here is a link to the GitHub page for the ASP.NET MVC Boilerplate project, for which I am doing this research and where you can look at my code.

这里有一个到ASP的GitHub页面的链接。NET MVC样板项目,我正在做这个研究,你可以看看我的代码。

#4


1  

Don't rely too much on http status codes.

不要太依赖http状态码。

I have worked with a few bad web developers over the last couple of years that have incorrectly used them in their responses.

在过去的几年里,我与一些糟糕的web开发人员合作过,他们在他们的回复中错误地使用了这些工具。

I may look for codes within 200-299 for an indication of success. I may look for codes >500 to indicate a server failure.

我可以在200-299范围内查找代码,以确定是否成功。我可以查找>500代码来指示服务器故障。

Beyond that, I use a selfish approach i.e. if you are making a request that your are expecting to have a package of data returned to you, then inspect the data. If there is no data or if the data is bad then I know for certain that there was a problem, because I didn't get what I needed to continue running my application in a nominal way.

除此之外,我使用了一种自私的方法,即如果您请求您希望返回一组数据,那么请检查数据。如果没有数据,或者数据很糟糕,那么我肯定知道有问题,因为我没有得到继续以名义方式运行应用程序所需的东西。

#1


2  

An interesting question, IMHO.

一个有趣的问题,恕我直言。

These three errors (403, 404 and 500) are the most common errors that can happen to the real user accessing your site with a standard browser.

这三个错误(403、404和500)是真正使用标准浏览器访问站点的用户最常见的错误。

On other hand, the HTTP standard was written for both server and agent developers in order to define how both sides should operate. Naturally, the standard browsers like IE, Chrome, Firefox, etc. as well as the standard robots like Google or Bing bots correctly fulfill the requirements, but some proprietary written agent may send a malformed request, and the standard provides the set of codes the server should send in this situation. For example, if the Content-Length field is missed the server returns the error code 411. However, you shouldn't provide user-friendly pages for such a situation.

另一方面,HTTP标准是为服务器和代理开发人员编写的,目的是定义双方应该如何操作。当然,IE、Chrome、Firefox等标准浏览器以及谷歌或Bing bots等标准机器人能够正确地满足需求,但一些专有的书面代理可能会发送错误的请求,标准提供了服务器在这种情况下应该发送的一组代码。例如,如果错过了Content-Length字段,服务器将返回错误代码411。但是,您不应该为这种情况提供用户友好的页面。

The code 408 (Request timeout) is explained in the standard as following:

代码408(请求超时)在标准中解释如下:

"The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."

在服务器准备等待的时间内,客户端没有发出请求。客户可以在以后的任何时候重复请求而不做任何修改。”

and it also not a case you should make user-friendly page for.

这也不是一个你应该做用户友好页面的情况。

To make a long story short, don't worry :)

长话短说,别担心:

#2


3  

There may be another way: this solution uses 1 custom-error page to handle all types (I think?)

可能还有其他的方法:这个解决方案使用一个自定义错误页面来处理所有类型(我认为?)

[1]: Remove all 'customErrors' & 'httpErrors' from Web.config

[1]:从Web.config中删除所有“自定义错误”和“httpErrors”。

[2]: Check 'App_Start/FilterConfig.cs' looks like this:

[2]:检查FilterConfig App_Start /。cs的看起来像这样:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }
}

[3]: in 'Global.asax' add this method:

[3]:在“全球。asax”添加这个方法:

public void Application_Error(Object sender, EventArgs e)
{
    Exception exception = Server.GetLastError();
    Server.ClearError();

    var routeData = new RouteData();
    routeData.Values.Add("controller", "ErrorPage");
    routeData.Values.Add("action", "Error");
    routeData.Values.Add("exception", exception);

    if (exception.GetType() == typeof(HttpException))
    {
        routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());
    }
    else
    {
        routeData.Values.Add("statusCode", 500);
    }

    Response.TrySkipIisCustomErrors = true;
    IController controller = new ErrorPageController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();
}

[4]: Add 'Controllers/ErrorPageController.cs'

[4]:添加“控制器/ ErrorPageController.cs”

public class ErrorPageController : Controller
{
    public ActionResult Error(int statusCode, Exception exception)
    {
         Response.StatusCode = statusCode;
         ViewBag.StatusCode = statusCode + " Error";
         return View();
    }
}

[5]: in 'Views/Shared/Error.cshtml'

[5]:在“视图/共享/ Error.cshtml”

@model System.Web.Mvc.HandleErrorInfo
@{
    ViewBag.Title = (!String.IsNullOrEmpty(ViewBag.StatusCode)) ? ViewBag.StatusCode : "500 Error";
}

<h1 class="error">@(!String.IsNullOrEmpty(ViewBag.StatusCode) ? ViewBag.StatusCode : "500 Error"):</h1>

//@Model.ActionName
//@Model.ContollerName
//@Model.Exception.Message
//@Model.Exception.StackTrace

#3


2  

I'm trying to find out the answer also. My code looks scarily like yours. This is a great question with so few views, I've set a bounty on this question. I myself have handled the following codes so far:

我也想找出答案。我的代码看起来像你的一样。这是一个很好的问题,几乎没有什么观点,我已经对这个问题下了定论。到目前为止,我自己已经处理了以下代码:

<system.webServer>
  <!-- Custom error pages -->
  <httpErrors errorMode="Custom" existingResponse="Replace">
    <!-- Redirect IIS 400 Bad Request responses to the error controllers bad request action. -->
    <remove statusCode="400" />
    <error statusCode="400" responseMode="ExecuteURL" path="/error/badrequest" />
    <!-- Redirect IIS 401 Unauthorized responses to the error controllers unauthorized action. -->
    <remove statusCode="401" />
    <error statusCode="401" responseMode="ExecuteURL" path="/error/unauthorized" />
    <!-- Redirect IIS 403.14 Forbidden responses to the error controllers not found action. 
         A 403.14 happens when navigating to an empty folder like /Content and directory browsing is turned off
         See http://rehansaeed.co.uk/securing-the-aspnet-mvc-web-config/ and http://www.troyhunt.com/2014/09/solving-tyranny-of-http-403-responses.html -->
    <error statusCode="403" subStatusCode="14" responseMode="ExecuteURL" path="/error/notfound" />
    <!-- Redirect IIS 404 Not Found responses to the error controllers not found action. -->
    <remove statusCode="404" />
    <error statusCode="404" responseMode="ExecuteURL" path="/error/notfound" />
    <!-- Redirect IIS 500 Internal Server Error responses to the error controllers internal server error action. -->
    <remove statusCode="500" />
    <error statusCode="500" responseMode="ExecuteURL" path="/error" />
  </httpErrors>
</system.webServer>

My reasoning is as follows:

我的推理如下:

  • 400 - Controllers have the BadRequest() method built in and you may want to return this when a parameter passed to the action is invalid.
  • 400 -控制器内置了BadRequest()方法,当传递给操作的参数无效时,您可能希望返回这个方法。
  • 401 - Applying the Authorize attribute to a controller or action causes a 401 Unauthorized response. Controllers also have the Unauthorized() method built in.
  • 向控制器或操作应用授权属性会导致401未授权响应。控制器中还内置了未授权的()方法。
  • 403.14 - Redirect these to 404 Not Found responses as a Forbidden is just plain wrong (See Securing your web.config and Troy Hunt's blog for more information).
  • 403.14 -将它们重定向到404未找到的响应作为禁止是完全错误的(参见保护您的web。config和Troy Hunt的博客获取更多信息)。
  • 404 - Thrown when the user browses to a page not found.
  • 404 -当用户浏览未找到的页面时抛出。
  • 500 - Thrown when something goes catastrophically wrong.
  • 500 -当发生灾难性的错误时抛出。

Overall I feel you should handle those codes that you yourself are going to use. The problem is that IIS does all kinds of strange things and we need to handle some of it's incorrect or invalid responses such as the 403.14 I listed above.

总的来说,我觉得你应该处理你自己将要使用的那些代码。问题是IIS会做各种奇怪的事情,我们需要处理一些不正确或无效的响应,如我上面列出的403.14。

Here is a complete list of IIS HTTP Status Codes and Sub-Status Codes which might be useful to our cause. I have a feeling the 403 Forbidden response should also be supported as it seems to be a fairly prominent response thrown by IIS.

下面是IIS HTTP状态码和子状态码的完整列表,它们可能对我们的目标有用。我有一种感觉,403的禁止响应也应该得到支持,因为它似乎是由IIS抛出的一个相当突出的响应。

One interesting thing I discovered while Googling is that navigating to:

我在谷歌上发现的一件有趣的事情是:

yoursite/<script></script>

Returns a 500 Internal Server from IIS. I feel this should return a 404. The IIS error page does not tell us what the Sub-Status Code is and I would be interested to know how we can find out, so that we can redirect the 500.Something to a 404 Not Found page.

从IIS返回一个500个内部服务器。我觉得应该返回404。IIS错误页面没有告诉我们子状态代码是什么,我很想知道如何查找,以便我们可以重定向500。404页面未找到。

Here is a link to the GitHub page for the ASP.NET MVC Boilerplate project, for which I am doing this research and where you can look at my code.

这里有一个到ASP的GitHub页面的链接。NET MVC样板项目,我正在做这个研究,你可以看看我的代码。

#4


1  

Don't rely too much on http status codes.

不要太依赖http状态码。

I have worked with a few bad web developers over the last couple of years that have incorrectly used them in their responses.

在过去的几年里,我与一些糟糕的web开发人员合作过,他们在他们的回复中错误地使用了这些工具。

I may look for codes within 200-299 for an indication of success. I may look for codes >500 to indicate a server failure.

我可以在200-299范围内查找代码,以确定是否成功。我可以查找>500代码来指示服务器故障。

Beyond that, I use a selfish approach i.e. if you are making a request that your are expecting to have a package of data returned to you, then inspect the data. If there is no data or if the data is bad then I know for certain that there was a problem, because I didn't get what I needed to continue running my application in a nominal way.

除此之外,我使用了一种自私的方法,即如果您请求您希望返回一组数据,那么请检查数据。如果没有数据,或者数据很糟糕,那么我肯定知道有问题,因为我没有得到继续以名义方式运行应用程序所需的东西。