11

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

 3 years ago
source link: http://developer.51cto.com/art/202101/642925.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

NRfYjyZ.jpg!mobile

ASP.Net Core 是微软开源的跨平台、可扩展、轻量级的模块化框架,可用于构建高性能的web应用程序。中间件组件可以注入到 ASP.Net Core 请求管道中实现对 Request 和 Response 的定制和修改。

ASP.Net Core 中间件可以用于检查、路由或者修改流转于Pipeline的Request和Response。本文将会讨论如何使用这些中间件来实现一些高级操作。

Use,Run,Map方法

介绍Use、Map,Run方法常用来一起构建 HTTP Pipeline 管道,下面快速浏览一下这些方法和它们的用途。

  • Use

该方法将会执行一个委托,然后将 交接棒 传给Pipeline的下一个中间件,因该方法短暂拥有交接棒,所以该方法可用于 短路操作。

  • Run

该方法会执行委托并返回结果。

  • Map

该方法将有条件地执行委托并返回结果。

注册中间件

中间件是在 Startup.Configure 中进行注册,调用方法就是 Use*系列扩展方法,下面是注册中间件的语法。

public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
{ 
    app.UseMyCustomMiddleware<MyCustomMiddleware>(); 
} 

需要注意的是,中间件的执行顺序和你注册的顺序是保持一致的。

Invoke 方法

每个中间件都包含一个 Invoke() 方法, 这个方法参数是 HttpContext 的一个实例,本中间件的业务逻辑会在下一个中间件的执行前后都会被执行,如果你有点懵的话,可以了解一下什么叫:递归调用,如下面代码注释所示:

public async Task Invoke(HttpContext context) 
{ 
    // Write code here that will be executed before the 
    // next middleware is called 
        await _next.Invoke(context); // call next middleware 
    // Write code here that will be executed after the 
    //next middleware is called  
} 

分流 Http 管道

Map系扩展方法,比如:Map 和 MapWhen,它们常用于给 pipeline 管道操作进行分流,前者是基于 Request path 进行分流,后者是基于指定的 谓语动词 进行分流。

下面的代码片段展示了如何使用 Map 方法对 Request Pipeline 进行分流。

public class Startup 
{ 
    private static void MapRequestA(IApplicationBuilder app) 
    { 
        app.Run(async context => 
        { 
            await context.Response.WriteAsync("This is MapRequestA"); 
        }); 
    } 
    private static void MapRequestB(IApplicationBuilder app) 
    { 
        app.Run(async context => 
        { 
            await context.Response.WriteAsync("This is MapRequestB"); 
        }); 
    } 
    private static void MapRequestC(IApplicationBuilder app) 
    { 
        app.Run(async context => 
        { 
            await context.Response.WriteAsync("This is MapRequestC"); 
        }); 
    } 
    public void Configure(IApplicationBuilder app) 
    { 
        app.Map("/mapRequestPathA", MapRequestA); 
        app.Map("/mapRequestPathB", MapRequestB); 
        app.Map("/mapRequestPathB", MapRequestC); 
 
        app.Run(async context => 
        { 
            await context.Response.WriteAsync("Hello World!"); 
        }); 
    } 
   //Other methods 
} 

MapWhen 方法接受两个参数:

  • Func<HttpContext, bool> predicate
  • delegate action

你可以在 Startup.Configure 方法中拒绝 text/xml 格式的 request,如下代码所示:

public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
        { 
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
            } 
            app.MapWhen(context => context.Request.ContentType.Equals 
            ("text/xml", StringComparison.InvariantCultureIgnoreCase), 
            (IApplicationBuilder applicationBuilder) => 
            { 
                applicationBuilder.Run(async context => 
                { 
                    await Task.FromResult(context.Response.StatusCode = StatusCodes.Status406NotAcceptable); 
                }); 
            }); 
            app.UseMvc(); 
        } 

使用 UseWhen

UseWhen方法可以用于有条件的执行中间件,下面的代码片段展示了如果当前 Request 请求路径是以 /api 开头的话,执行一个指定的中间件,代码如下:

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), applicationBuilder => 
{ 
    applicationBuilder.UseCustomMiddleware(); 
}); 

请注意,UseWhen 不像 MapWhen,前者会继续执行后面的中间件逻辑,不管当前 UseWhen 的委托函数返回的是 true 还是 false,如果有点懵的话,可以理解一下下面的代码:

app.UseMiddlewareA(); 
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), applicationBuilder => 
{ 
    applicationBuilder.UseMiddlewareB(); 
}); 
app.UseMiddlewareC(); 

如果中间件没有短路,那么中间件A和C肯定会被执行的,而且当请求路径是以 /api 开头时,中间件B也会被调度。

在 ASP.Net Core 请求处理管道中有一个中间件链,所有请求和响应都流经此管道,当新请求到达时,这些中间件要么处理请求,要么将请求传递给管道中的下一个组件,对于更复杂的请求处理,我们可以使用 Map 和 MapWhen 方法来分流管道,并可以使用 UseWhen 有条件的执行中间件。

译文链接:https://www.infoworld.com/article/3429602/how-to-use-conditional-middleware-in-aspnet-core.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK