.NET 6 Web API中Serilog注入ILogger至自定义过滤器失败
解决.NET 6 Web API中自定义ExceptionFilterAttribute注入ILogger的依赖注入异常
问题根源
你遇到的异常是因为直接通过options.Filters.Add<MyErrorHandlingAttribute>()添加过滤器时,ASP.NET Core不会通过依赖注入容器实例化这个Attribute,而是尝试直接创建对象,但你的Attribute类只有带ILogger参数的构造函数,框架无法自动解析这个依赖,因此抛出无法解析服务的异常。
另外,建议使用泛型版本的ILogger<T>而非非泛型ILogger,这样日志会包含具体的类名称,更便于排查问题。
解决方案
步骤1:修改自定义ExceptionFilterAttribute
将构造函数改为接收泛型ILogger<MyErrorHandlingAttribute>,并实现异常日志逻辑:
public class MyErrorHandlingAttribute : ExceptionFilterAttribute { private readonly ILogger<MyErrorHandlingAttribute> _logger; public MyErrorHandlingAttribute(ILogger<MyErrorHandlingAttribute> logger) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public override void OnException(ExceptionContext context) { // 记录异常及请求路径信息 _logger.LogError( context.Exception, "未处理异常,请求路径:{RequestPath}", context.HttpContext.Request.Path); // 可添加自定义异常处理逻辑,比如设置统一返回结果 context.Result = new ObjectResult(new { Message = "服务器内部错误" }) { StatusCode = StatusCodes.Status500InternalServerError }; base.OnException(context); } }
步骤2:正确注册过滤器(二选一)
方式一:使用TypeFilterAttribute包装
这种方式无需提前注册过滤器为服务,框架会通过DI解析依赖:
builder.Services.AddControllers(options => { options.Filters.Add(new TypeFilterAttribute(typeof(MyErrorHandlingAttribute))); });
方式二:注册为服务后使用ServiceFilterAttribute
先将过滤器注册为Scoped服务,再通过ServiceFilter添加:
// 注册过滤器为Scoped服务 builder.Services.AddScoped<MyErrorHandlingAttribute>(); builder.Services.AddControllers(options => { options.Filters.Add(new ServiceFilterAttribute(typeof(MyErrorHandlingAttribute))); });
额外说明
你的Serilog配置是正常的(控制器中能正常记录日志即可证明),问题出在ASP.NET Core过滤器的实例化机制上,和Serilog本身无关。使用上述两种方式注册过滤器后,DI容器会自动注入ILogger实例,异常即可解决。
内容的提问来源于stack exchange,提问作者Pea Kay See Es
相关产品推荐
相关产品推荐

