Netcore——Middleware中间件(1)

一、什么是中间件

比如流水线工作 每个工人做的事情都很唯一 ,如果要真正生产出一个手机,要经过每一个工人的处理才能得到一个完整的手机。如果上一个工人对手机做了,一些修改 那么这个修改也会保留到下一个工人手中,工人之间共享的是这部手机。

ASP.NET Core的处理流程是一个管道,而中间件是装配到管道中的用于处理请求和响应的组件。中间件按照装配的先后顺序执行,并决定是否进入下一个组件。中间件管道的处理流程如下图。

请添加图片描述
在这里插入图片描述
在这里插入图片描述

二、中间件连接器

Use、Map,Run方法常用来一起构建 HTTP Pipeline 管道。这几个方法把不同的中间件委托连接起来。

1.Use

该方法将会执行一个委托,然后将 交接棒
传给Pipeline的下一个中间件,因该方法短暂拥有 交接棒
,所以该方法可用于 短路操作
在这里插入图片描述

// 向应用程序的请求管道中添加一个Func委托,这个委托其实就是所谓的中间件。

// context参数是HttpContext,表示HTTP请求的上下文对象

// next参数表示管道中的下一个中间件委托,如果不调用next,则会使管道短路

// 用Use可以将多个中间件链接在一起

public class Startup

{

    public void Configure(IApplicationBuilder app)

    {

        app.Use(async (context, next) =>

        {

                await context.Response.WriteAsync("进入第一个委托 执行下一个委托之前\r\n");

                //调用管道中的下一个委托

                await next.Invoke();

                await context.Response.WriteAsync("结束第一个委托 执行下一个委托之后\r\n");

            });

            app.Run(async context =>

        {

                await context.Response.WriteAsync("进入第二个委托\r\n");

                await context.Response.WriteAsync("Hello from 2nd delegate.\r\n");

                await context.Response.WriteAsync("结束第二个委托\r\n");

            });

    }

}

在这里插入图片描述

2.Run

Run()方法中只有一个RequestDelegate委托类型的参数,没有Next参数,所以Run()方法也叫终端中间件,不会将请求传递给下一个中间件,也就是发生了“短路”。看下面的代码:

在这里插入图片描述

// Run方法向应用程序的请求管道中添加一个RequestDelegate委托

// 放在管道最后面,终端中间件

app.Run(handler: async context => 

{

    await context.Response.WriteAsync(text: "Hello World1\r\n");

});

app.Run(handler: async context =>

{

    await context.Response.WriteAsync(text: "Hello World2\r\n");

});

3.Map

Map作为惯例,将管道分流。Map根据给定请求路径匹配将请求管道分流。如果请求路径以指定路径开始,则执行分支。

在这里插入图片描述

public class Startup

{

    private static void HandleMapTest1(IApplicationBuilder app)

    {

        app.Run(async context =>

        {

            await context.Response.WriteAsync("Map Test 1");

        });

    }



    private static void HandleMapTest2(IApplicationBuilder app)

    {

        app.Run(async context =>

        {

            await context.Response.WriteAsync("Map Test 2");

        });

    }



    public void Configure(IApplicationBuilder app)

    {

        app.Map("/map1", HandleMapTest1);



        app.Map("/map2", HandleMapTest2);



        app.Run(async context =>

        {

            await context.Response.WriteAsync("Hello from non-Map delegate. <p>");

        });

    }

}

三、自定义中间件

1. 基于约定的方式

定义一个Middleware的类。

public class RequestCultureMiddleware

{

    private readonly RequestDelegate _next;

    public RequestCultureMiddleware(RequestDelegate next)

    {

        _next = next;

    }



    public async Task InvokeAsync(HttpContext context)

    {

        var cultureQuery = context.Request.Query["culture"];

        if (!string.IsNullOrWhiteSpace(cultureQuery))

        {

            var culture = new CultureInfo(cultureQuery);

            CultureInfo.CurrentCulture = culture;

            CultureInfo.CurrentUICulture = culture;

        }

        await _next(context);

    }

}

编写完成之后,需要手动的将类注册到管道中才能生效,注册方式如下所示。

app.UseMiddleware<RequestCultureMiddleware>();

2.实现IMiddleware的方式

实现IMiddleware接口。

public class RequestCultureOtherMiddleware:IMiddleware

{

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)

    {

        var cultureQuery = context.Request.Query["culture"];

        if (!string.IsNullOrWhiteSpace(cultureQuery))

        {

            var culture = new CultureInfo(cultureQuery);

            CultureInfo.CurrentCulture = culture;

            CultureInfo.CurrentUICulture = culture;

        }

        await next(context);

    }

}

手动将中间件注册到容器中。

services.AddSingleton<IMiddleware,RequestCultureOtherMiddleware>();

注册到管道中

app.UseMiddleware<RequestCultureOtherMiddleware>();
posted @ 2022-07-20 09:14  有诗亦有远方  阅读(29)  评论(0编辑  收藏  举报  来源