webapi中间件没有使用终结点中间件时的注意事项
最小webapi
最小webapi默认的中间件配置是这样的
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
最小webapi没有使用app.UseRouting()
和app.UseEndpoints
。
这种情况下我们添加的所有中间件其实都是位于终结点路由中间件EndpointRoutingMiddleware
和终结点中间件EndpointMiddleware
之间的中间件。
也就是说这些中间件全都执行了之后,Action才会执行。
加入我们写了一个自定义404页面的中间件,并把它注册进去。
app.Use(async (context, next) =>
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
context.Response.ContentType = "text/html;charset=utf-8";
context.Response.WriteAsync("来到了知识的荒原");
await next(context);
});
这个中间件不会以我们预料的方式运行,他会在每次请求中都被调用,而不是找不到路由时才调用。
就是因为没有注册app.UseEndpoints
的终结点中间件时,不存在终结点之后的中间件。而终结点之后的中间件才会在找不到路由,找不到终结点时被调用。
终结点中间件应该是在找到了终结点时会短路管道,找不到时调用next(context)
。
所以我们必须显式调用app.UseEndpoints
,然后再到后面再注册我们的404中间件。这才会达到我们的预期。
必须注意的的是如果app.UseEndpoints
被调用,那么app.UseRouting()
也必须被调用。
所以这种情况下正确的写法是
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.UseEndpoints(endpoints=>{});
app.Use(async (context, next) =>
{
context.Response.StatusCode = StatusCodes.Status404NotFound;
context.Response.ContentType = "text/html;charset=utf-8";
context.Response.WriteAsync("来到了知识的荒原");
await next(context);
});
app.Run();
检验
我们可以取一下终结点信息看看是不是这样
app.Use(async (context, next) =>
{
var endpoint = context.GetEndpoint();
await next(context);
});
把这个中间件添加到app.UseRouting()
之前,app.UseRouting()
之后,再加一个到app.UseEndpoints
之后。
我们能发现只有再app.UseRouting()
和app.UseRouting()
之间的那个中间件才能取到终结点信息,其他的两个里面终结点endpoint = null
MSDN
最小webapi中的默认情况下,我们的中间件就在图中Custom middlewares
的地方。我们改了之后就能同时在Endpoint
之后加中间件了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构