在ASP.NET MVC 5中处理404,403,500个http代码

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

I have spent the whole day trying to implement custom handler for HTTP errors. I am using MVC 5 and IIS 7. There are a lot of good suggestions HERE. Since I need to take care not only for 404 I have tried THIS option.

我花了一整天的时间尝试为HTTP错误实现自定义处理程序。我正在使用MVC 5和IIS 7.这里有很多好的建议。因为我不仅需要注意404我已经尝试过这个选项。

Ultimately I need to be able to handle all these cases

最终,我需要能够处理所有这些情况

Should be able to handle all unmatched routes localhost/404_test/test/test/test/test/12/23

应该能够处理所有不匹配的路由localhost / 404_test / test / test / test / test / 12/23

Should be able to handle HTTP 500 throw exception from the action

应该能够处理来自动作的HTTP 500抛出异常

Should be able to handle all html errors for example 400. localhost/404_test/ddsa

应该能够处理所有html错误,例如400. localhost / 404_test / ddsa

Should be able to handle "file extension like url" localhost/404_test/test.cdd

应该能够处理“像url这样的文件扩展名”localhost / 404_test / test.cdd

Using the code in the provided link also by updating web.config as shown below I am able to handle all cases except "file extension like url". I am receiving blank page. It looks like IIS is overwriting response. It was the same for unmatched routes before I added

通过更新web.config使用提供的链接中的代码,如下所示,我能够处理除“文件扩展名像url”之外的所有情况。我收到空白页。看起来IIS正在覆盖响应。在我添加之前,对于不匹配的路线来说是一样的

<httpErrors errorMode="Custom" existingResponse="PassThrough" >

Here is the rout map for unmatched cases :

这是不匹配案例的路线图:

        routes.MapRoute("NotFound", "{*url}",
            new { controller = "Error", action = "NotFound" });

Any suggestions how to have this implemented ? I see *.com works exactly the way I want to have, but I have no idea how it is implemented.

有任何建议如何实施?我看到*.com完全按照我想要的方式工作,但我不知道它是如何实现的。

Web.config

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
     <httpErrors errorMode="Custom" existingResponse="PassThrough" >
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" subStatusCode="-1" responseMode="ExecuteURL" path="/Error/NotFound" />
      <remove statusCode="500" subStatusCode="-1" />
      <error statusCode="500" subStatusCode="-1" responseMode="ExecuteURL" path="/Error/ServerError" />
    </httpErrors>
  </system.webServer>

1 个解决方案

#1


0  

This is a solution I have implemented before in an MVC3 app, so it was a while ago. It should handle any invalid URL as well as unhandled exceptions thrown from the application. You should be able to combine this with the code from links above for handling other 40x errors. This code is running on www.carbsandcals.com.

这是我之前在MVC3应用程序中实现的解决方案,所以它是不久前的。它应该处理任何无效的URL以及从应用程序抛出的未处理的异常。您应该能够将此与上面链接中的代码结合使用,以处理其他40x错误。此代码在www.carbsandcals.com上运行。

In web.config:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="400" subStatusCode="-1" />
    <error statusCode="400" prefixLanguageFilePath="" path="/Error/Error/400" responseMode="ExecuteURL" />
    <error statusCode="404" prefixLanguageFilePath="" path="/Error/Error/404" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/Error/Error/500" responseMode="ExecuteURL" />
</httpErrors>

In Global.asax, to handle "view not found" errors thrown by the MVC view engine:

在Global.asax中,处理MVC视图引擎抛出的“未查找的视图”错误:

    protected void Application_Error()
    {
        Exception ex = Server.GetLastError();

        bool handleError = false;

        int errorCode = 500;

        if (handleError = (ex is InvalidOperationException && ex.Message.Contains("or its master was not found or no view engine supports the searched locations. The following locations were searched")))
        {
            errorCode = 404;
        }
        else if (handleError = ex is HttpException)
        {
            errorCode = ((HttpException)ex).GetHttpCode();
        }

        if (handleError)
        {
            Server.ClearError();

            Server.TransferRequest("/error/error/" + errorCode);
        }
    }

I'd prefer not to have to test against the error message content but I couldn't find a better way of distinguishing this error from other InvalidOperationExceptions.

我宁愿不必测试错误消息内容,但我找不到更好的方法来区分此错误与其他InvalidOperationExceptions。

Caveat: Although this will handle HttpRequestValidationException errors, the processing of the error page may throw further exceptions of the same type (as the URL is still invalid). I noticed this with Html.RenderPartial and an ASCX as well as interacting with the SiteMap. In this case it may be better to redirect to a simple view or a static page.

警告:虽然这会处理HttpRequestValidationException错误,但错误页面的处理可能会抛出相同类型的更多异常(因为URL仍然无效)。我注意到了Html.RenderPartial和ASCX以及与SiteMap的交互。在这种情况下,重定向到简单视图或静态页面可能更好。

The error controller sets the Response.StatusCode so that the correct HTTP code is sent back to the client.

错误控制器设置Response.StatusCode,以便将正确的HTTP代码发送回客户端。

#1


0  

This is a solution I have implemented before in an MVC3 app, so it was a while ago. It should handle any invalid URL as well as unhandled exceptions thrown from the application. You should be able to combine this with the code from links above for handling other 40x errors. This code is running on www.carbsandcals.com.

这是我之前在MVC3应用程序中实现的解决方案,所以它是不久前的。它应该处理任何无效的URL以及从应用程序抛出的未处理的异常。您应该能够将此与上面链接中的代码结合使用,以处理其他40x错误。此代码在www.carbsandcals.com上运行。

In web.config:

<httpErrors errorMode="Custom" existingResponse="Replace">
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <remove statusCode="400" subStatusCode="-1" />
    <error statusCode="400" prefixLanguageFilePath="" path="/Error/Error/400" responseMode="ExecuteURL" />
    <error statusCode="404" prefixLanguageFilePath="" path="/Error/Error/404" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/Error/Error/500" responseMode="ExecuteURL" />
</httpErrors>

In Global.asax, to handle "view not found" errors thrown by the MVC view engine:

在Global.asax中,处理MVC视图引擎抛出的“未查找的视图”错误:

    protected void Application_Error()
    {
        Exception ex = Server.GetLastError();

        bool handleError = false;

        int errorCode = 500;

        if (handleError = (ex is InvalidOperationException && ex.Message.Contains("or its master was not found or no view engine supports the searched locations. The following locations were searched")))
        {
            errorCode = 404;
        }
        else if (handleError = ex is HttpException)
        {
            errorCode = ((HttpException)ex).GetHttpCode();
        }

        if (handleError)
        {
            Server.ClearError();

            Server.TransferRequest("/error/error/" + errorCode);
        }
    }

I'd prefer not to have to test against the error message content but I couldn't find a better way of distinguishing this error from other InvalidOperationExceptions.

我宁愿不必测试错误消息内容,但我找不到更好的方法来区分此错误与其他InvalidOperationExceptions。

Caveat: Although this will handle HttpRequestValidationException errors, the processing of the error page may throw further exceptions of the same type (as the URL is still invalid). I noticed this with Html.RenderPartial and an ASCX as well as interacting with the SiteMap. In this case it may be better to redirect to a simple view or a static page.

警告:虽然这会处理HttpRequestValidationException错误,但错误页面的处理可能会抛出相同类型的更多异常(因为URL仍然无效)。我注意到了Html.RenderPartial和ASCX以及与SiteMap的交互。在这种情况下,重定向到简单视图或静态页面可能更好。

The error controller sets the Response.StatusCode so that the correct HTTP code is sent back to the client.

错误控制器设置Response.StatusCode,以便将正确的HTTP代码发送回客户端。