全局过滤器
2026/4/22大约 1 分钟
全局过滤器
除了能在接口声明中使用 IApiFilterAttribute 子类的特性标注之外,还可以在接口注册时的配置添加 IApiFilter 类型的过滤器。
这些过滤器将对整个接口生效,且优先于通过特性标注的 IApiFilterAttribute 类型执行。
配置全局过滤器
services.AddHttpApi<IUserApi>().ConfigureHttpApi(o =>
{
o.GlobalFilters.Add(new UserFilter());
});实现自定义过滤器
public class UserFilter : IApiFilter
{
public async Task OnRequestAsync(ApiRequestContext context)
{
// 请求前处理
var userContext = context.HttpContext.ServiceProvider.GetRequiredService<IUserContext>();
context.HttpContext.RequestMessage.Headers.Add("X-User-Id", userContext.UserId);
}
public async Task OnResponseAsync(ApiResponseContext context)
{
// 响应后处理
var response = context.HttpContext.ResponseMessage;
// 记录日志、监控等
}
}过滤器执行顺序
- 接口级别的
GlobalFilters(按添加顺序) - 接口声明的
IApiFilterAttribute特性 - 方法声明的
IApiFilterAttribute特性
常见应用场景
请求签名
public class SignFilter : IApiFilter
{
public async Task OnRequestAsync(ApiRequestContext context)
{
var signService = context.HttpContext.ServiceProvider.GetRequiredService<SignService>();
var sign = signService.SignValue(DateTime.Now);
context.HttpContext.RequestMessage.AddUrlQuery("sign", sign);
}
public Task OnResponseAsync(ApiResponseContext context) => Task.CompletedTask;
}
services.AddHttpApi<IExternalApi>().ConfigureHttpApi(o =>
{
o.GlobalFilters.Add(new SignFilter());
});请求日志
public class RequestLoggingFilter : IApiFilter
{
private readonly ILogger<RequestLoggingFilter> _logger;
public RequestLoggingFilter(ILogger<RequestLoggingFilter> logger)
{
_logger = logger;
}
public async Task OnRequestAsync(ApiRequestContext context)
{
var request = context.HttpContext.RequestMessage;
_logger.LogInformation("Request: {Method} {Uri}", request.Method, request.RequestUri);
}
public async Task OnResponseAsync(ApiResponseContext context)
{
var response = context.HttpContext.ResponseMessage;
_logger.LogInformation("Response: {StatusCode}", response.StatusCode);
}
}租户上下文注入
public class TenantFilter : IApiFilter
{
public async Task OnRequestAsync(ApiRequestContext context)
{
var tenantContext = context.HttpContext.ServiceProvider.GetRequiredService<ITenantContext>();
context.HttpContext.RequestMessage.Headers.Add("X-Tenant-Id", tenantContext.TenantId);
}
public Task OnResponseAsync(ApiResponseContext context) => Task.CompletedTask;
}依赖注入
全局过滤器支持构造函数注入:
services.AddHttpApi<IUserApi>().ConfigureHttpApi(o =>
{
o.GlobalFilters.Add(new SignFilter()); // 如果 SignFilter 有依赖,需要先注册到 DI
});
// 或者使用工厂方法
services.AddHttpApi<IUserApi>().ConfigureHttpApi((o, sp) =>
{
o.GlobalFilters.Add(sp.GetRequiredService<SignFilter>());
});