.NET 6 HttpLogging中间件:如何过滤指定控制器的请求体日志
.NET 6 Web API 过滤指定控制器的请求体日志
要实现禁止记录部分控制器的请求体日志,你可以通过自定义IHttpLoggingInterceptor拦截器灵活控制日志字段,以下是两种可行方案:
方案一:直接根据控制器名称过滤
实现IHttpLoggingInterceptor接口,在拦截逻辑中判断请求对应的控制器名称,动态移除RequestBody日志字段:
- 创建自定义拦截器类
public class SensitiveRequestBodyLoggingInterceptor : IHttpLoggingInterceptor { public ValueTask OnLogAsync(HttpLoggingInterceptorContext context) { var endpoint = context.HttpContext.GetEndpoint(); if (endpoint != null) { // 获取控制器描述信息 var controllerDescriptor = endpoint.Metadata.GetMetadata<ControllerActionDescriptor>(); if (controllerDescriptor != null) { // 指定需要跳过日志的控制器(比如AccountController、PaymentController) var sensitiveControllers = new[] { "AccountController", "PaymentController" }; if (sensitiveControllers.Contains(controllerDescriptor.ControllerTypeInfo.Name, StringComparer.OrdinalIgnoreCase)) { // 移除RequestBody字段,避免记录敏感请求体 context.LogFields &= ~HttpLoggingFields.RequestBody; } } } return ValueTask.CompletedTask; } }
- 在Program.cs中注册拦截器并配置HttpLogging
builder.Services.AddHttpLogging(options => { var loggingFields = HttpLoggingFields.RequestPropertiesAndHeaders | HttpLoggingFields.ResponsePropertiesAndHeaders | HttpLoggingFields.ResponseStatusCode | HttpLoggingFields.RequestQuery | HttpLoggingFields.RequestBody; options.LoggingFields = loggingFields; // 添加自定义拦截器到HttpLogging配置 options.Interceptors.Add<SensitiveRequestBodyLoggingInterceptor>(); }); // 务必将HttpLogging中间件添加到请求管道 app.UseHttpLogging();
方案二:用自定义特性标记需要过滤的控制器
这种方式更灵活,通过特性标记指定哪些控制器/Action需要跳过请求体日志:
- 定义自定义特性
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class SkipRequestBodyLoggingAttribute : Attribute { }
- 在目标控制器/Action上添加特性
// 给整个控制器添加特性,跳过所有Action的请求体日志 [SkipRequestBodyLogging] [ApiController] [Route("api/account")] public class AccountController : ControllerBase { // 或者只给单个Action添加特性 [SkipRequestBodyLogging] [HttpPost("login")] public IActionResult Login(LoginRequest request) { // 业务逻辑... return Ok(); } }
- 修改拦截器逻辑,检查特性存在性
public class SensitiveRequestBodyLoggingInterceptor : IHttpLoggingInterceptor { public ValueTask OnLogAsync(HttpLoggingInterceptorContext context) { var endpoint = context.HttpContext.GetEndpoint(); if (endpoint != null && endpoint.Metadata.GetMetadata<SkipRequestBodyLoggingAttribute>() != null) { // 存在特性则移除RequestBody日志字段 context.LogFields &= ~HttpLoggingFields.RequestBody; } return ValueTask.CompletedTask; } }
- 同样在Program.cs中注册该拦截器(同方案一的注册步骤)
注意事项
- 拦截器会在日志记录前动态修改
LogFields,不会影响其他正常的日志字段 - 如果需要更细粒度的控制,还可以结合路由、请求方法等条件扩展拦截逻辑
内容的提问来源于stack exchange,提问作者Ozkan Tuzemen
相关产品推荐
相关产品推荐

