如何在Web.Config中完全使用customErrors?

时间:2016-02-13 21:15:02

标签: c# asp.net error-handling asp.net-mvc-5

我为我的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));
                }
            }
        }

然后,在我的ErrorController里面我做:

     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();
            }
...

所以第一次一切正常 但是!!代码重复,因为NotFound或ServerError页面不在Shared文件夹中。这些页面应该在customErrors属性中设置但是我根本不需要它。我终于得到了这个错误:ERR_TOO_MANY_REDIRECTS因此。

我整天都在阅读有关这方面的任何答案,而且发布代码的每个人都采用与我相同的模式,无论我尝试什么,都没有用。

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

我还在global.asax中评论这两行,因为我读到的所有地方都说我们需要删除它们才能完成这项工作。

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

另外,由于绝望,如果,我得到了这个答案:

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;但它没有用!

那么,我怎样才能完全获得customErrors并在我的项目中管理我自己的错误处理程序?

1 个答案:

答案 0 :(得分:1)

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

我通过执行ErrorController的方式做得不好。

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

我发现通过使用ServerTransfert,我们可以获得customErrors属性。这是最终解决方案(已测试):

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的评论指出了我正确的方向。

大卫

相关问题