如何在Web API项目中记录依赖项解析期间抛出的异常?

时间:2014-01-17 20:01:05

标签: c# asp.net-web-api autofac

如果控制器的依赖项解析失败,如何设置IIS中托管的Web API 2(版本5)项目以记录错误?我正在使用Autofac Web API 2集成(版本3.1)进行DI。

在我的Global.asax.cs中,我有以下内容:

public class Global : HttpApplication {
    protected void Application_Start() {
        var resolver = new AutofacWebApiDependencyResolver(_container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;

        // other initialization

        GlobalConfiguration.Configuration.EnsureInitialized(); 

    }

    protected void Application_Error(Object sender, EventArgs e){
        Exception exception = Server.GetLastError();
        if (exception != null) {
            _log.Error("Application error", exception);
        }
    }
}

在使用AutofacDependencyResolver的类似MVC项目中,这足以记录在创建控制器时Autofac无法解析依赖关系时引发的Autofac.Core.DependencyResolutionException,但在我的Web API项目中,这似乎不是工作,要么没有抛出异常,要么我没有设置正确的日志记录处理程序。相反,不会记录任何消息,而是将500响应返回给客户端。

如果在依赖项解析期间没有抛出任何错误(我的模块设置正确),那么一切正常,控制器将被解析并按预期处理请求。

我还设置了一些其他异常记录器,但也没有记录此异常:

  • 处理未处理的异常事件:AppDomain.CurrentDomain.UnhandledException + = CurrentDomain_UnhandledException(在Global.asax.cs中)
  • 设置从ExceptionFilterAttribute派生的异常日志记录筛选器。这会记录控制器处理请求时抛出的异常,但不会记录在依赖项解析期间抛出的异常。

1 个答案:

答案 0 :(得分:7)

这可以通过使用新的Global Error Handling在Web API 2.1中完成。

public class Log4NetExceptionLogger : ExceptionLogger {
    private static readonly ILog _log = LogManager.GetLogger("{your logger name here}");
    public override void Log(ExceptionLoggerContext context) {
        if (context == null) {
            throw new ArgumentNullException("context");
        }
        // When the framework calls an exception logger or an exception handler, it will always provide an Exception and a Request.
        // http://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling&referringTitle=Specs
        if (context.Exception == null) {
            throw new ArgumentException("context.Exception is null", "context");
        }
        if (context.Request == null) {
            throw new ArgumentException("context.Request is null", "context");
        }

        _log.Error(context.Request, context.Exception);
    }
}

// In GlobalConfiguration setup in Global.asax.cs
config.Services.Add(typeof(IExceptionLogger), new Log4NetExceptionLogger());