ASP.NET Core中UseRouting/UseEndpoints对端点匹配的影响及代码问题解析
ASP.NET Core 路由问题:为何默认配置下路由无法匹配?
我正在学习ASP.NET Core Routing文档,文档说明:应用通常无需调用UseRouting或UseEndpoints,WebApplicationBuilder会配置中间件管道,将Program.cs中添加的中间件用这两个方法包裹;但应用可通过显式调用调整它们的运行顺序。
我编写的代码本应在/路由返回Inspect Endpoint.,其他路径返回Out of available endpoints,但实际始终返回后者。代码如下:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => "Inspect Endpoint."); app.Run(async context => { await context.Response.WriteAsync("Out of available endpoints"); }); app.Run();
但如果在app.MapGet(...)前添加以下语句,结果就符合预期:
app.UseRouting(); app.UseEndpoints(_ => { });
请问这是为什么?我哪里理解错了?
原因解析
核心问题出在中间件管道的执行顺序上:
WebApplication的隐式路由包装规则
WebApplication确实会自动包装UseRouting和UseEndpoints,但它的逻辑是:所有通过MapXXX定义的端点路由,都会被自动归类到隐式的UseEndpoints块内;而在MapXXX之后添加的中间件,会被放在这个隐式UseEndpoints的后面。初始代码的执行顺序问题
在你最初的代码中:
app.MapGet("/", ...)被放入隐式的UseEndpoints中间件- 紧接着的
app.Run(...)是终端中间件,被添加到了隐式UseEndpoints的后面 - ASP.NET Core中间件按添加顺序依次执行,请求进来时会先触发
app.Run(...),直接返回结果,根本没走到路由匹配逻辑,所以所有路径都会返回Out of available endpoints。
- 显式添加路由中间件后的变化
当你显式调用app.UseRouting()和app.UseEndpoints(_ => { })后:
UseRouting先加入管道,负责解析请求路由UseEndpoints块被提前,后续的app.MapGet("/", ...)会被合并到这个显式的UseEndpoints中- 最后的
app.Run(...)终端中间件被放在UseEndpoints之后 - 请求进来时先经过路由匹配:如果是
/路径,MapGet的端点会处理请求并返回;如果是其他路径,路由匹配失败,才会走到app.Run(...)返回预期提示。
- 无需显式调用的正确写法
其实不用添加那两行显式代码,只要调整中间件顺序,把app.Run(...)放在MapGet之前即可:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Run(async context => { await context.Response.WriteAsync("Out of available endpoints"); }); app.MapGet("/", () => "Inspect Endpoint."); app.Run();
WebApplication会把所有MapXXX路由放在隐式的UseEndpoints里,而UseEndpoints默认位置在所有非路由中间件的前面,这样请求进来时会先执行路由匹配,匹配成功就返回,失败才会走到app.Run(...)。
内容的提问来源于stack exchange,提问作者vy8
相关产品推荐
相关产品推荐

