在ASP.NET Core的请求管道中,中间件按照注册顺序依次处理请求,每个中间件都可以选择将请求传递给下一个中间件,或者提前终止请求处理流程,这种方式就是中间件短路请求。短路请求可以避免不必要的后续中间件执行,减少资源消耗,在权限校验、请求过滤等场景中非常实用。

什么是Middleware短路请求
Middleware短路请求指的是当前中间件处理完请求逻辑后,不再调用下一个中间件的Invoke方法中的next委托,直接生成响应返回给客户端,后续的请求处理流程会被直接终止。比如我们在权限校验中间件中,发现用户没有登录,就可以直接返回401状态码,不需要再执行后续的业务逻辑中间件。
基础短路请求实现
实现短路请求的核心是不调用next委托,下面通过一个简单的示例来演示。首先创建一个自定义中间件类:
// 自定义短路中间件
public class ShortCircuitMiddleware
{
private readonly RequestDelegate _next;
public ShortCircuitMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// 判断请求路径是否为需要短路的路径
if (context.Request.Path.StartsWithSegments("/short-circuit"))
{
// 设置响应状态码和内容,不调用_next,实现短路
context.Response.StatusCode = 403;
await context.Response.WriteAsync("请求被短路,禁止访问");
return;
}
// 其他请求正常传递给下一个中间件
await _next(context);
}
}
然后在Program.cs中注册这个中间件:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 注册自定义短路中间件
app.UseMiddleware<ShortCircuitMiddleware>();
// 后续的业务中间件
app.MapGet("/", () => "正常请求响应");
app.Run();
当我们访问/short-circuit路径时,请求会被短路,直接返回403状态码和提示内容,不会执行到后面的根路径中间件。
使用内置中间件实现短路
ASP.NET Core内置了很多中间件也支持短路逻辑,比如UseAuthorization中间件,当用户未授权时就会直接返回401响应,不需要额外编写代码。下面是一个使用内置授权中间件实现短路的示例:
var builder = WebApplication.CreateBuilder(args);
// 添加授权服务
builder.Services.AddAuthorization();
var app = builder.Build();
// 注册授权中间件,未授权请求会被短路返回401
app.UseAuthorization();
// 需要授权的端点
app.MapGet("/secure", () => "安全资源")
.RequireAuthorization();
app.Run();
中间件分支实现
中间件分支指的是根据请求的特征,将请求分流到不同的中间件管道中处理,分支内部的中间件不会影响主管道的其他请求。常用的分支中间件有Map、MapWhen、UseWhen。
Map分支中间件
Map会根据请求路径的前缀来创建分支,匹配到的请求会走分支内的中间件,不匹配的走主流程:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 路径前缀为/api的请求走这个分支
app.Map("/api", apiApp =>
{
apiApp.Use(async (context, next) =>
{
context.Response.Headers.Add("X-API-Version", "1.0");
await next();
});
apiApp.MapGet("/user", () => "API用户数据");
});
// 主流程中间件
app.MapGet("/", () => "主页内容");
app.Run();
MapWhen分支中间件
MapWhen可以根据自定义的条件来创建分支,比如根据请求头、查询参数等:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 当查询参数中包含debug=true时走这个分支
app.MapWhen(context => context.Request.Query.ContainsKey("debug"), debugApp =>
{
debugApp.Use(async (context, next) =>
{
await context.Response.WriteAsync("当前处于调试模式n");
await next();
});
debugApp.MapGet("/info", () => "调试信息");
});
app.MapGet("/", () => "正常内容");
app.Run();
UseWhen分支中间件
UseWhen和MapWhen类似,但是分支处理完之后会回到主流程继续执行后续中间件,不会完全隔离:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 当请求头包含X-Custom-Header时,先执行分支逻辑,再回到主流程
app.UseWhen(context => context.Request.Headers.ContainsKey("X-Custom-Header"), customApp =>
{
customApp.Use(async (context, next) =>
{
context.Response.Headers.Add("X-Processed-By", "CustomBranch");
await next();
});
});
app.MapGet("/", () => "处理后的内容");
app.Run();
短路和分支结合使用
在实际开发中,我们经常会在分支中间件中实现短路逻辑,比如针对特定路径的请求做权限校验,校验不通过就短路返回。下面是一个结合示例:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 针对/admin路径的分支,实现权限短路
app.Map("/admin", adminApp =>
{
adminApp.Use(async (context, next) =>
{
// 简单模拟权限校验,没有token就短路返回401
if (!context.Request.Headers.ContainsKey("Authorization"))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("未授权,禁止访问管理页面");
return;
}
await next();
});
adminApp.MapGet("/dashboard", () => "管理后台仪表盘");
});
app.MapGet("/", () => "主页");
app.Run();
注意事项
- 短路请求一定要在调用
next委托之前完成响应内容的写入,否则可能会出现响应已经启动无法修改的错误。 - 分支中间件的注册顺序很重要,先注册的分支会优先匹配请求。
- 使用
UseWhen分支时,分支内的短路不会影响主流程的其他请求,只会终止当前分支内的后续中间件执行。 - 不要在中间件中多次调用
next委托,这会导致请求管道执行异常。
C#_MiddlewareASP.NET_Core请求短路中间件分支请求管道修改时间:2026-07-13 22:48:51