如何在Web.Config中完全摆脱自定义错误

本文关键字:自定义 错误 Web Config | 更新日期: 2023-09-27 18:34:38

我为我的 MVC5 项目实现了一个自定义错误处理程序,如果它不是 customErrors 属性,一切都会好起来的。我将解释:当我在应用程序中遇到错误时,我会在 Global.asax 的 void Application_Error中捕获它,如下所示:

protected void Application_Error(object sender, EventArgs e)
        {
            var httpContext = ((HttpApplication)sender).Context;
            ExecuteErrorController(httpContext, Server.GetLastError());
        }
public static void ExecuteErrorController(HttpContext httpContext, Exception exception)
        {
            if (!exception.Message.Contains("NotFound") && !exception.Message.Contains("ServerError"))
            {
                var routeData = new RouteData();
                routeData.Values["area"] = "Administration";
                routeData.Values["controller"] = "Error";
                routeData.Values["action"] = "Insert";
                routeData.Values["exception"] = exception;
                using (Controller controller = new ErrorController())
                {
                    ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
                }
            }
        }

然后,在我的错误控制器中,我这样做:

     public ActionResult Insert(Exception exception)
            {
                ErrorSignal.FromCurrentContext().Raise(exception);
                Server.ClearError();
                Response.Clear();
                switch (Tools.GetHttpCode(exception)) // (int)HttpStatusCode.NotFound;
                {
                    case 400:
                        return RedirectToAction("BadRequest");
                    case 401:
                        return RedirectToAction("Unauthorized");
                    case 403:
                        return RedirectToAction("Forbidden");
                    case 404:
                        return RedirectToAction("NotFound");
                    case 500:
                        return RedirectToAction("ServerError");
                    default:
                        return RedirectToAction("DefaultError");
                }
            }
    public ActionResult Unauthorized()
            {
                return View();
            }
...

所以第一次一切正常但!!代码重复,因为"未找到"或"服务器错误"页不在"共享"文件夹中。这些页面应该在自定义错误属性中设置,但问题是我根本不需要它。我终于得到了这个错误:ERR_TOO_MANY_REDIRECTS因为这个。

读了一整天来寻找任何答案,而且每个发布代码的人都做和我一样的模式,无论我尝试什么,都没有效果。

注意我绝望的 if 条件:if (!exception.Message.Contains("NotFound"( && !exception.Message.Contains("ServerError"((

我还在global.asax中评论了这两行,因为无论我在哪里阅读,它都说我们需要删除它们才能完成此操作。

//GlobalConfiguration.Configure(WebApiConfig.Register);
//FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

另外,由于 desparate if,我得到了这个答案:

Runtime Error
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed. 
Details: To enable the details of this specific error message to be viewable on the local server machine, please create a <customErrors> tag within a "web.config" configuration file located in the root directory of the current web application. This <customErrors> tag should then have its "mode" attribute set to "RemoteOnly". To enable the details to be viewable on remote machines, please set "mode" to "Off".

<!-- Web.Config Configuration File -->
<configuration>
    <system.web>
        <customErrors mode="RemoteOnly"/>
    </system.web>
</configuration>

我也试过Response.TrySkipIisCustomErrors = true;,但它不起作用!

那么,我怎样才能完全摆脱自定义错误并在项目中管理我自己的错误处理程序呢?

如何在Web.Config中完全摆脱自定义错误

好的,感谢 RoteS 的评论。我终于找到了完成这项工作所需的东西!

我通过执行错误控制器来做到这一点的方式并不好。

using (Controller controller = new ErrorController())
                {
                    ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
                }

我发现通过使用ServerTransfert代替,我们可以获得自定义错误属性。这是最终解决方案(经过测试(:

protected void Application_Error(object sender, EventArgs e)
        {
            // Response.TrySkipIisCustomErrors = true; I don't know if I will need it someday.
            var httpContext = ((HttpApplication)sender).Context;
            var exception = Server.GetLastError();
            ErrorSignal.FromCurrentContext().Raise(exception);
            Server.ClearError();
            Response.Clear();
            string relativePath = "~/Administration/Error/{0}";
            switch (Tools.GetHttpCode(exception))
            {
                case (int)HttpStatusCode.BadRequest:
                    Server.TransferRequest(string.Format(relativePath, "BadRequest"));
                    break;
                case (int)HttpStatusCode.Unauthorized:
                    Server.TransferRequest(string.Format(relativePath, "Unauthorized"));
                    break;
                case (int)HttpStatusCode.Forbidden:
                    Server.TransferRequest(string.Format(relativePath, "Forbidden"));
                    break;
                case (int)HttpStatusCode.NotFound:
                    Server.TransferRequest(string.Format(relativePath, "NotFound"));
                    break;
                case (int)HttpStatusCode.InternalServerError:
                    Server.TransferRequest(string.Format(relativePath, "ServerError"));
                    break;
                default:
                    Server.TransferRequest(string.Format(relativePath, "DefaultError"));
                    break;
            }
        }

感谢 RoteS 的评论,为我指明了正确的方向。

大卫