【问题标题】:Handle global and HTTP exception with ASP.NET MVC使用 ASP.NET MVC 处理全局和 HTTP 异常
【发布时间】:2019-03-01 21:32:09
【问题描述】:

我正在尝试使用 Global.asax 文件中的 Application_Error() 事件使用带有正确 HTTP 状态代码的自定义错误页面来处理 Asp.Net MVC 中的全局(StatusCode 500)和 http 异常。为了简单起见,实际上对于所有类型的已处理异常,我只有相同的视图错误。

现在的问题是,当处理 500 异常时,它第一次进入 Application_Error 的 else 部分,然后返回 if 部分,最后返回 404 http 异常而不是 500 异常。

当处理 500 异常时,我如何通过在 Application_Error 的 else 部分停止运行来解决这个问题?

这是我的配置: web.config

<system.web>
   <customErrors mode="Off"/>
</system.web>

 <system.webServer>
      <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="400"/>
        <remove statusCode="401"/>
        <remove statusCode="403"/>
        <remove statusCode="404"/>
        <remove statusCode="500"/>
        <error statusCode="400" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="401" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="403" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="404" responseMode="ExecuteURL" path="/Error"/>
        <error statusCode="500" responseMode="ExecuteURL" path="/Error"/>
      </httpErrors>
</system.webServer>

方法 Application_Error():

public void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
        HttpException httpException = exception as HttpException;

        // Clear the response stream
        HttpContext httpContext = ((HttpApplication)sender).Context;
        httpContext.Response.Clear();
        httpContext.ClearError();

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


        if (exception.GetType() == typeof(HttpException)) //It's an Http Exception
        {
            routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());

            switch (routeData.Values["statusCode"])
            {
                case 400:
                    routeData.Values.Add("status", "400 - Bad Request");
                    break;
                case 401:
                    routeData.Values.Add("status", "401 - Access Denied");
                    break;
                case 403:
                    routeData.Values.Add("status", "403 - Forbidden");
                    break;
                case 404:
                    routeData.Values.Add("status", "404 - Page Not Found");
                    break;
                case 500:
                default:
                    routeData.Values.Add("status", "500 - Internal Server Error");
                    break;
            }
        }
        else
        {
            routeData.Values.Add("statusCode", 500);
            routeData.Values.Add("status", "500 - Internal Server Error");

        }

        // Avoid IIS7 getting in the middle
        httpContext.Response.TrySkipIisCustomErrors = true;

        // Call target Controller and pass the routeData.
        IController controller = new ErrorController();
        controller.Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
        Response.End();
        // clear error on server
        //Server.ClearError();
    }

控制器错误控制器:

public class ErrorController : Controller
    {
        // GET: /Error/
        public ActionResult Error(int statusCode, string status, Exception exception)
        {
            Response.StatusCode = statusCode;
            ViewBag.StatusCode = statusCode;
            ViewBag.Status = status;
            return View();
        }
    }

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-5


    【解决方案1】:

    这背后的原因是应用程序抛出的Exception的类型并不总是HttpException。它可能是SQLException, SystemException, IndexOutOfRangeException 等。状态码总是与HttpExceptions 相关联。这就是为什么您的代码首先进入else 部分,然后进入if 部分。

    虽然它不应该再次出现在if 部分,但如果它出现了,那么您必须检查您正在重定向用户的页面是否进一步抛出任何其他异常。

    我还建议从您的代码中删除最后一个参数,因为 Exception 是一种复杂类型,我们通常不会在 Get 请求中传递复杂类型。

    转换这个

    public ActionResult Error(int statusCode, string status, Exception exception)
    

    public ActionResult Error(int statusCode, string status)
    

    【讨论】:

    • 感谢您的回复
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2018-09-11
    • 2016-11-18
    • 1970-01-01
    • 2018-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多