asp.net核心中间件中Map和MapWhen分支的区别?

Posted

技术标签:

【中文标题】asp.net核心中间件中Map和MapWhen分支的区别?【英文标题】:difference between Map and MapWhen branch in asp.net core Middleware? 【发布时间】:2018-06-08 09:22:00 【问题描述】:

当我们对请求进行身份验证时,何时在 asp.net 核心中间件中使用 Map 和 MapWhen 分支。

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    app.Map("", (appBuilder) =>
    
        appBuilder.Run(async (context) => 
            await context.Response.WriteAsync("");
        );
    );

    app.MapWhen(context => context.Request.Query.ContainsKey(""), (appBuilder) =>
    
        appBuilder.Run(async (context) =>
        
            await context.Response.WriteAsync("");
        );

    );

【问题讨论】:

【参考方案1】:

接受的答案很有帮助,但并不完全准确。除了谓词逻辑之外,MapMapWhen 之间的主要区别在于 Map 会将 MapMiddleware 添加到管道(参见 here),而 MapWhen 将添加 MapWhenMiddleware 到管道(参见here)。这样做的效果是Map 将更新Request.PathRequest.PathBase 以考虑基于路径的分支(从Request.Path 中修剪匹配的路径段并将其附加到Request.PathBase),而看似等效的@ 987654334@ 谓词不会。这会影响使用该路径的任何下游,例如路由!

【讨论】:

这应该是公认的答案。如果地图中的中间件需要路径的第一部分,则尤其如此。例如,如果UseMvc() 在路由中需要前缀/api,则app.Map("/api", builder => builder.UseMvc()) 将不起作用。相反,最好使用app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), ... ); 这个答案解释了使用.Map(的一个非常重要的方面【参考方案2】:

Map 只能根据指定请求路径的匹配来分支请求。 MapWhen 更强大,它允许基于与当前HttpContext 对象一起操作的指定谓词的结果来分支请求。 到目前为止,HttpContext 包含有关 HTTP 请求的所有信息,MapWhen 允许您使用非常具体的条件来分支请求管道。

任何Map 调用都可以轻松转换为MapWhen,但反之则不然。例如这个Map 电话:

app.Map("SomePathMatch", (appBuilder) =>

    appBuilder.Run(async (context) => 

        await context.Response.WriteAsync("");
    );
);

相当于下面的MapWhen调用:

app.MapWhen(context => context.Request.Path.StartsWithSegments("SomePathMatch"), (appBuilder) =>

    appBuilder.Run(async (context) =>
    
        await context.Response.WriteAsync("");
    );
);

所以回答您的问题“何时使用 Map 和 MapWhen 分支”:当您仅基于请求路径分支请求时使用 Map。当您根据 HTTP 请求中的其他数据对请求进行分支时,请使用 MapWhen

【讨论】:

CodeFuller 这并不完全正确,请参阅下面@alex-lorimer 的答案以及我的评论中的示例。

以上是关于asp.net核心中间件中Map和MapWhen分支的区别?的主要内容,如果未能解决你的问题,请参考以下文章

asp.net核心中间件怎么做DI?

处理asp.net核心中的异常?

如何在 ASP.Net Core 中使用 条件中间件

ASP.NET Core Web API - 如何在中间件管道中隐藏 DbContext 事务?

csharp RequestCounter自定义中间件asp.net核心

在 ASP.NET 核心中创建 JWT 是不是有更简单的方法?又名“JWT 身份验证的最佳实践?”