2

出于测试目的,我有这个方法:

public ActionResult Index()
{
    System.Diagnostics.Debug.Write("Index");
    return new HttpNotFoundResult();
}

正在调用该方法(输出“索引”)。不知何故,它导致 aHttpException被抛出。在我的 Global.asax 文件中,我有一个Application_Error实现:

void Application_Error(object sender, EventArgs e)
{
    Exception exc = Server.GetLastError();
    if (exc is System.Web.HttpException)
    {
        string msg = "UrlReferrer: "
            + Context.Request.UrlReferrer + " UserAgent: " + Context.Request.UserAgent
            + " UserHostAddress: " + Context.Request.UserHostAddress + " UserHostName: "
            + Context.Request.UserHostName;

        ErrorHandler.Error(exc.Message, msg);
    }
    else {
        ...
    }
}

在系统处理完请求后调用此方法Index。我认为HttpNotFoundResult导致异常被抛出的原因 - 或者可能是任何ActionResult状态码为 404 的异常被抛出。

这很烦人,因为它绕过了OnException我的控制器上的处理程序。对于我的网站,Application_Error应该是最后的回退 - 大多数正常错误都打算在其他地方处理(由控制器或动作过滤器)。我只想Application_Error记录完全意外的异常,或者图像或 .js 文件之类的 404。

有没有办法阻止 asp.net 为程序生成的 404 引发异常?或者,有没有办法确定Application_Error是否HttpException是由程序生成的 404 引起的?

4

1 回答 1

2

您可以创建一个自定义异常过滤器来处理所有操作引发的 404 异常。您可以使用HttpContext.Items集合来跟踪它是否是程序引发的 404。

自定义异常过滤器

public class NotFoundExceptionFilter : IExceptionFilter
{        
    public void OnException(ExceptionContext filterContext)
    {
        // ignore if the exception is already handled or not a 404
        if (filterContext.ExceptionHandled || new HttpException(null, filterContext.Exception).GetHttpCode() != 404)
            return;

        filterContext.HttpContext.Items.Add("Programmatic404", true);
        filterContext.ExceptionHandled = true;
    }
}

您需要申请NotFoundExceptionFilter为全局过滤器。

Application_Error 事件

public static void Application_Error(object sender, EventArgs e)
{
    var httpContext = ((MvcApplication)sender).Context;

    // ignore if it is a programatically raised 404
    if(httpContext.Items["Programmatic404"] != null && bool.Parse(httpContext.Items["Programmatic404"].ToString()))
        return;

    // else, Log the exception
}
于 2012-12-03T14:38:22.603 回答