.NET Core中间件中Use方法如何定位下一个RequestDelegate委托?
理解ASP.NET Core中RequestDelegate的next委托调用逻辑
你的困惑核心在于ASP.NET Core中间件管道的构建方式——每个next委托其实就是当前中间件之后的整个剩余处理管道的入口,它的赋值和调用逻辑是通过反向链式包装实现的。
先拆解你的代码执行流程
当请求进入你的应用时,实际执行顺序是:
- 执行第一个
Use中间件的await context.Response.WriteAsync("HelloOne ");,输出HelloOne。 - 调用
next.Invoke(context),此时这个next指向第二个Use中间件的处理逻辑。 - 执行第二个
Use中间件的await context.Response.WriteAsync("HelloTwo");,输出HelloTwo。 - 调用
next.Invoke(context),此时这个next指向app.Run()的逻辑(Run是管道终点,内部没有额外操作,直接结束)。 - 所有中间件执行完毕,响应返回,最终结果是
HelloOne HelloTwo。
为什么next能找到下一个委托?
ASP.NET Core在构建中间件管道时,是从后往前逐个包装委托的:
- 首先处理最后调用的
app.Run(),它会生成一个没有后续逻辑的RequestDelegate(可以理解为管道的“终点委托”)。 - 然后处理倒数第二个
app.Use(),框架会把你传入的委托包装成一个新的RequestDelegate,同时把刚才的“终点委托”作为next参数传入这个Use的委托中。 - 接着处理第一个
app.Use(),同样把第二个Use包装后的委托作为next参数传入第一个Use的委托。
用伪代码模拟这个包装过程会更清晰:
// 1. app.Run()对应的终点委托 RequestDelegate finalDelegate = _ => Task.CompletedTask; // 2. 包装第二个Use的委托,把finalDelegate作为它的next RequestDelegate secondMiddleware = async context => { await context.Response.WriteAsync("HelloTwo"); await finalDelegate(context); // 这里的finalDelegate就是第二个Use的next }; // 3. 包装第一个Use的委托,把secondMiddleware作为它的next RequestDelegate firstMiddleware = async context => { await context.Response.WriteAsync("HelloOne "); await secondMiddleware(context); // 这里的secondMiddleware就是第一个Use的next }; // 最终请求入口就是firstMiddleware,触发后会按顺序调用整个链
简单来说,每个Use的next参数,都是框架提前为你准备好的“后续所有中间件的集合委托”,调用next.Invoke(context)就是把请求传递给后续的处理流程。
内容的提问来源于stack exchange,提问作者Yugraaj Sandhu
相关产品推荐
相关产品推荐

