中间件的概念及基本使用

什么是中间件

中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。

  1. 广义上来讲:Tomcat、WebLogic、Redis、IIS;狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。
  2. 中间件由前逻辑、next、后逻辑3部分组成,前逻辑为第一段要执行的逻辑代码、next为指向下一个中间件的调用、后逻辑为从下一个中间件执行返回所执行的逻辑代码。每个HTTP请求都要经历一系列中间件的处理,每个中间件对于请求进行特定的处理后,再转到下一个中间件,最终的业务逻辑代码执行完成后,响应的内容也会按照处理的相反顺序进行处理,然后形成HTTP响应报文返回给客户端。
  3. 中间件组成一个管道,整个ASP.NET Core的执行过程就是HTTP请求和响应按照中间件组装的顺序在中间件之间流转的过程。开发人员可以对组成管道的中间件按照需要进行自由组合。

中间件的三个概念

Map、Use和Run。Map用来定义一个管道可以处理哪些请求,Use和Run用来定义管道,一个管道由若干个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。

中间件的基本使用

此为案例,不推荐这样使用

cs 复制代码
app.Map("/test", async (appBuilder) =>
{
    appBuilder.Use(async (context, next) =>
    {
        context.Response.ContentType = "test/html";
        await context.Response.WriteAsync("1 Start<br/>");
        await next();
        await context.Response.WriteAsync("1 End<br/>");
    });
    appBuilder.Use(async (context, next) =>
    {
        await context.Response.WriteAsync("2 Start<br/>");
        await next();
        await context.Response.WriteAsync("2 End<br/>");
    });
    appBuilder.Run(async context =>
    {
        await context.Response.WriteAsync("Run<br/>");
    });
});

中间件类

简单的自定义中间件

  1. 如果中间件的代码比较复杂,或者我们需要重复使用一个中间件的话,我们最好把中间件的代码放到一个单独的"中间件类"中。
  2. 中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。这个类还需要定义一个名字为Invoke或InvokeAsync的方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和Invoke(或InvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。

需求

检查请求中是否有password=123的查询字符串,而且会把请求报文体按照Json格式尝试解析为dynamic类型的对象,并且把dynamic对象放入context.Items中供后续的中间件或者Run使用。

实现

Nuget:Install-Package Dynamic.Json

cs 复制代码
public class CheckMiddleware
{
    private readonly RequestDelegate _next;
    public CheckMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        //从请求的查询字符串中获取名为password的参数值
        string password = context.Request.Query["password"];
        if (password == "123")
        {
            //检查请求的内容类型是否为JSON
            if (context.Request.HasJsonContentType())
            {
                //获取请求体的流
                Stream stream = context.Request.BodyReader.AsStream();
                //将流中的JSON数据解析为动态对象,并将解析后的对象存入Items集合
                dynamic obj = await DJson.ParseAsync(stream);
                context.Items["BodyJson"] =obj;
            }
            await _next(context);
        }
        else
        {
            context.Response.StatusCode = 403;
        }
    }
}

Program.cs
app.Map("/test", async (appBuilder) =>
{
    appBuilder.UseMiddleware<CheckMiddleware>();
    appBuilder.Run(async context =>
    {
        dynamic? obj = context.Items["BodyJson"];
        if (obj != null)
        {
            await context.Response.WriteAsync($"{obj}");
        }
    });
});
相关推荐
ASKCOS16 小时前
DeerFlow Agent 中间件架构:用插件化链彻底告别 Agent 继承式开发
中间件·架构
阿昌喜欢吃黄桃18 天前
RocketMq事务消息原理
java·中间件·消息队列·rocketmq·mq
半夜修仙19 天前
延迟队列的介绍及常见问题
java·数据库·中间件·rabbitmq
手握风云-19 天前
一条消息的旅程:RabbitMQ 学习与实践(一)
中间件·rabbitmq
RH23121120 天前
2026.6.8Linux
java·数据库·中间件
理人综艺好会20 天前
双Token机制在实际项目中的应用与实践
中间件·token
番茄去哪了21 天前
神领物流面试题(一)
java·大数据·中间件
念何架构之路21 天前
消息中间件
中间件
都说名字长不会被发现21 天前
Spring Boot Starter 中间件账号密码加密方案设计与实现
java·spring boot·后端·中间件
瀚高PG实验室22 天前
java中间件无法连接数据库
java·数据库·中间件·瀚高数据库