毯子错误处理不能正常工作

时间:2016-10-25 15:36:06

标签: asp.net-mvc error-handling

我一直在研究一些内部应用程序,但我无法让错误处理工作正常。当用户点击存在的控制器时,一切正常。如果用户尝试转到不存在的控制器的URL,则错误处理全部正常,但是当提供视图时,它在浏览器中显示为HTML。我做错了什么?

我抓取Global.asax中的所有应用程序错误,然后将它们转发给错误控制器。

private void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();
#if !DEBUG
    exception.AddExceptionDataValue("User", User?.Identity?.Name);
    exception.HandleException();
#endif
    var httpException = exception as HttpException;
    if (httpException != null)
    {
        Response.StatusCode = httpException.GetHttpCode();
    }
    Server.ClearError();
    Response.TrySkipIisCustomErrors = true;
    IController controller = new ErrorController();
    var routeData = new RouteData();
    routeData.Values.Add("controller", "Error");
    routeData.Values.Add("action", "Index");
    routeData.Values.Add("message", exception == null ? "Details not available." : exception.Message);
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    controller.Execute(rc);
}

这导致在每次错误时将错误消息传递给我的错误控制器。唯一的区别是向用户显示的内容。

编辑:我发现这只发生在IIS Express上。当它在具有IIS的真实服务器上运行时,所有错误页面都像第一个示例中那样呈现。 IIS Express仅出于某种原因向用户显示原始HTML。我只能通过使用web.config <httpErrors>部分来处理每个状态代码并转发到控制器操作,但这似乎是不必要的,因为我的Global.asax将在生产中处理它而没有问题。

现有控制器内部生成的错误示例(即使该操作不存在):

Application Error

尝试访问不存在的控制器(它是包含错误消息的整个文档)生成的错误示例:

Application Error as markup

1 个答案:

答案 0 :(得分:0)

您是否需要将这些错误发送给另一个控制器?

你可以从HandleErrorAttribute

创建一个自定义实现
public class CustomErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        base.OnException(filterContext);

        var controllerName = (string) filterContext.RouteData.Values["controller"];
        var actionName = (string) filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

        filterContext.Result = new ViewResult
        {
            ViewName = "Error",
            ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
            TempData = filterContext.Controller.TempData
        };
        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = 500;
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

并将其添加到FilterConfig

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomErrorAttribute());
    }