执行逻辑
sequenceDiagram
request->>endpoint: http请求
endpoint->>filter: 执行筛选器逻辑
filter-->>request: 跳过endpoint逻辑,返回response
filter->>endpoint: 执行endpoint逻辑
endpoint->>request: 返回response
官方描述
开发人员可以实现支持以下操作的业务逻辑:
- 在
endpoint处理程序 前、后 运行代码 - 检查和修改
endpoint程序调用期间提供的参数 - 截获
endpoint处理程序的相应行为
在以下场景中,筛选器很有用:
- 验证已发送到终结点的请求参数和正文
- 记录有关请求和响应的信息
- 验证请求是否面向受支持的 API 版本
如何使用
个人推荐使用继承IEndpointFilter接口,这样可以逻辑复用。
日志打印
namespace Filters.EndpointFilters;
// 日志输出
// Before next
// Endpoint
// After next
app.MapGet("/", () =>
{
app.Logger.LogInformation("Endpoint");
return "Test of multiple filters";
})
.AddEndpointFilter<LoggerEndpointFilter>();
public class LoggerEndpointFilter : IEndpointFilter
{
protected readonly ILogger Logger;
// 依赖注入 ILoggerFactory
protected ABCEndpointFilters(ILoggerFactory loggerFactory)
{
Logger = loggerFactory.CreateLogger<ABCEndpointFilters>();
}
public virtual async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context,
EndpointFilterDelegate next)
{
// 之前执行
Logger.LogInformation("Before next");
// 执行endpoint逻辑
var result = await next(context);
// 之后执行
Logger.LogInformation("After next");
return result;
}
}
模型验证
public class TodoIsValidFilter : IEndpointFilter
{
private ILogger _logger;
// 依赖注入
public TodoIsValidFilter(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<TodoIsValidFilter>();
}
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext efiContext,
EndpointFilterDelegate next)
{
// 获取参数
var todo = efiContext.GetArgument<Todo>(0);
// 验证
var validationError = Utilities.IsValid(todo!);
// 模型不符合
if (!string.IsNullOrEmpty(validationError))
{
// 记录日志
_logger.LogWarning(validationError);
// 跳过endpoint逻辑,返回http请求结果
return Results.Problem(validationError);
}
// 模型符合,执行endpoint逻辑
return await next(efiContext);
}
}
总结
实现起来很简单,但是考验你的创造能力。