当我的基本控制器的构造函数中调用的方法抛出错误时,不会触发全局应用的自定义异常过滤器

Globally applied custom exception filter is not triggered when error is thrown by a method called in the constructor of my base controller

我有这个自定义异常过滤器:

public class CustomExceptionFilter : IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        try
        {
            if (filterContext == null) return;

            // Log error details to the DB
        }
        catch
        {
            // Intentional empty catch
        }
    }
}

在 RegisterGlobalFilters 中全局应用(从 Application_Start 调用):

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

然后我的 BaseController 上有一个受保护的构造函数调用此方法:

public Site GetSiteByUrl(string host)
{
    var urls = _repo.Urls.Where(x => x.Host == host);

    if (urls == null || !urls.Any())
        throw new MultiTenancyException(String.Format("No URL record exists for request. Host = \"{0}\"", host));

    if (urls.Count() > 1)
        throw new MultiTenancyException(String.Format("Multiple URL records exist for request. Host = \"{0}\"",
            host));

    var url = urls.Single();
    var site = _repo.Sites.Single(x => x.Id == url.SiteId);

    if (!url.Enabled)
        throw new MultiTenancyException(
            String.Format("URL record found for request, but is not Enabled. Host = \"{0}\", Site = \"{1}\"",
                host, site.Name));

    return site;
}

当抛出此方法中的任何 MultiTenancyExceptions 时,不会触发我的 CustomExceptionFilter 的 OnException 事件。

我试过:

两者都无济于事。回顾 CustomExceptionFilter 捕获的异常日志,唯一记录的错误似乎是由系统异常(NullReference、ArgumentOutOfRange 等)引起的,这可能是相关的,也可能只是巧合。

我已经在谷歌上搜索了大约 30 分钟,此时我开始摸不着头脑,所以我正在寻找任何明智的想法。

谢谢。

来自 GlobalFilterCollection 的过滤器仅适用于控制器操作执行时发生的异常。

要捕获在操作执行之前或之后发生的异常,您应该在 Global.asax 文件中定义 Application_Error 方法:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

    void Application_Error(object sender, EventArgs e)
    {
        // handle global errors here
    }
}