Asp.Net Core 5.0注册HttpClient时如何注入ILogger记录失败请求体
ASP.NET Core 自定义HttpClient注入日志与失败请求体记录方案
1. ILogger注入报错修复
报错 Unable to resolve service for type 'Microsoft.Extensions.Logging.ILogger' 的根本原因是:ASP.NET Core 依赖注入容器默认仅注册了泛型版本的ILogger<TCategoryName>,未注册非泛型的ILogger,你只需要将SomeHttpClient构造函数中的参数类型替换为泛型版本即可:
public class SomeHttpClient : ISomeHttpClient { private readonly HttpClient _httpClient; private readonly ILogger<SomeHttpClient> _logger; // 修改构造函数的ILogger为泛型ILogger<SomeHttpClient> public SomeHttpClient(HttpClient httpClient, ILogger<SomeHttpClient> logger) { _httpClient = httpClient; _logger = logger; } // 业务方法省略 }
修改后即可正常注入日志组件,不会再报服务解析错误。
2. 非成功状态码请求体记录实现
推荐使用DelegatingHandler(请求委托处理器)实现该需求,该方案可以无侵入拦截HttpClient的所有请求响应流程,逻辑可复用,不需要修改业务代码:
步骤1:自定义请求拦截处理器
public class LogFailedRequestHandler : DelegatingHandler { private readonly ILogger<LogFailedRequestHandler> _logger; public LogFailedRequestHandler(ILogger<LogFailedRequestHandler> logger) { _logger = logger; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // 启用请求体缓冲,避免读取后业务侧无法再次获取请求体 if (request.Content != null) { await request.Content.LoadIntoBufferAsync(); } // 执行后续请求流程 var response = await base.SendAsync(request, cancellationToken); // 状态码非2xx时记录请求体 if (!response.IsSuccessStatusCode && request.Content != null) { string requestBody = await request.Content.ReadAsStringAsync(cancellationToken); _logger.LogError("HTTP请求失败: 地址={RequestUrl}, 方法={Method}, 状态码={StatusCode}, 请求体={RequestBody}", request.RequestUri, request.Method, response.StatusCode, requestBody); } return response; } }
步骤2:注册处理器到自定义HttpClient
修改原服务注册代码,添加处理器的注册和绑定:
// 注册自定义请求处理器 services.AddTransient<LogFailedRequestHandler>(); services.AddHttpClient<ISomeHttpClient, SomeHttpClient>(client => { client.BaseAddress = new Uri(Configuration["Url"]); client.DefaultRequestHeaders.Add("Accept", "application/json"); }) // 绑定自定义处理器,拦截该HttpClient的所有请求 .AddHttpMessageHandler<LogFailedRequestHandler>();
如果你只需要给单个HttpClient临时加日志逻辑,也可以直接在SomeHttpClient的业务请求方法中,拿到HttpResponseMessage后判断IsSuccessStatusCode属性,手动读取请求体记录日志即可。
内容的提问来源于stack exchange,提问作者osotorrio
相关产品推荐
相关产品推荐

