我有两段代码
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Use(async (context, next) =>
{
if (context.Request.Headers["token"] != "my_token")
{
context.Response.StatusCode = 401;
return;
}
await next();
});
app.Run();
和
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) =>
{
if (context.Request.Headers["token"] != "my_token")
{
context.Response.StatusCode = 401;
return;
}
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
区别仅在于app.MapGet()
的位置
对于这两个代码,首先执行app.Use()
,然后执行app.MapGet()
这是什么原因?为什么管道不总是基于中间件的序列来执行?
引用ASP.NET核心中的路由,路由基础:
应用程序通常不需要调用
UseRouting
或UseEndpoints
。WebApplicationBuilder配置了一个中间件管道,该管道用UseRouting
和UseEndpoints
封装在Program.cs
中添加的中间件。但是,应用程序可以通过显式调用这些方法来更改UseRouting
和UseEndpoints
的运行顺序。例如,以下代码对UseRouting
:进行显式调用app.Use(async (context, next) => { // ... await next(context); }); app.UseRouting(); app.MapGet("/", () => "Hello World!");
[…]
如果前面的示例不包括对UseRouting的调用,那么自定义中间件将在路由匹配中间件之后运行。
所以答案是因为默认情况下,WebApplication.CreateBuilder(args)
会对请求管道进行排序,以便端点总是最后运行,除非您明确表示要更改该顺序。