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

image
最小webapi中的默认情况下,我们的中间件就在图中Custom middlewares的地方。我们改了之后就能同时在Endpoint之后加中间件了。

posted @ 2024-05-03 20:20  ggtc  阅读(9)  评论(0编辑  收藏  举报
//右下角目录