如何让自定义中间件在FluentValidation之前执行?
.NET 7 Web API 优先返回无效路由提示的中间件顺序调整方案
问题根源
FluentValidation.AspNetCore 默认会自动将其 ValidationMiddleware 注入到请求管道中,且位置在 UseAuthorization() 之前。如果你的自定义路由合法性验证中间件放在 UseAuthorization() 之后,请求会先经过FluentValidation的验证逻辑——即便路由无效,只要请求体符合某个合法路由的参数结构,FluentValidation会先抛出验证错误并返回响应,导致你的路由验证逻辑根本没机会执行。
解决方法:手动控制FluentValidation中间件位置
通过禁用FluentValidation的自动中间件注册,手动将其放到自定义路由验证中间件之后,确保路由验证优先执行。
步骤1:修改服务注册逻辑
在配置FluentValidation时,禁用自动中间件注册,并添加你的验证器:
// 配置FluentValidation,禁用自动中间件注册 builder.Services.AddFluentValidationAutoValidation(options => { options.DisableAutomaticMiddlewareRegistration = true; }) .AddFluentValidationClientsideAdapters(); // 注册项目中的验证器(替换为你的验证器所在程序集) builder.Services.AddValidatorsFromAssemblyContaining<YourRequestValidator>();
步骤2:调整中间件管道顺序
在Program.cs的管道配置部分,先添加你的自定义路由验证中间件,再手动添加FluentValidation的ValidationMiddleware:
app.UseRouting(); // 优先添加自定义路由合法性验证中间件 app.UseMiddleware<RouteValidationMiddleware>(); // 手动添加FluentValidation验证中间件 app.UseMiddleware<FluentValidation.AspNetCore.ValidationMiddleware>(); app.UseAuthorization(); app.MapControllers();
关键注意点
确保你的RouteValidationMiddleware在检测到无效路由时,直接短路管道,示例逻辑如下:
public class RouteValidationMiddleware { private readonly RequestDelegate _next; public RouteValidationMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 自定义路由合法性判断逻辑:检查是否匹配任何已定义的控制器路由 var endpoint = context.GetEndpoint(); if (endpoint == null) { // 路由无效,直接返回404响应 context.Response.StatusCode = StatusCodes.Status404NotFound; await context.Response.WriteAsJsonAsync(new { message = "无效路由" }); return; // 短路管道,后续中间件不再执行 } // 路由合法,继续执行后续中间件 await _next(context); } }
这样配置后,请求会先经过路由验证:如果路由无效,直接返回404提示;如果路由合法,再进入FluentValidation的验证流程,符合预期逻辑。
内容的提问来源于stack exchange,提问作者BrianS
相关产品推荐
相关产品推荐

