当前位置: 首页 > article >正文

中间件的概念及基本使用

什么是中间件

中间件是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是用来执行最终的核心应用逻辑。

中间件的基本使用

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

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

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}");
        }
    });
});


http://www.kler.cn/a/530895.html

相关文章:

  • 【leetcode100】路径总和Ⅲ
  • 使用 PyTorch 实现逻辑回归并评估模型性能
  • 一、TensorFlow的建模流程
  • LeetCode:300.最长递增子序列
  • 简单的SQL语句的快速复习
  • SpringBoot Web开发(SpringMVC)
  • 基于springboot+vue的航空散货调度系统
  • 五、定时器实现呼吸灯
  • 51单片机 05 矩阵键盘
  • 阿里云盘PC端打不开解决办法
  • [paddle] 矩阵相关的指标
  • Day 27 卡玛笔记
  • 如何在Arduino上使用NodeMCU
  • 基于Kamailio的VoIP管理系统方案(技术栈:MySQL + Redis + Gin + Vue.js
  • 计算机网络网络层进阶:NAT、ARP 与 IP 系列技术全析!!!
  • 业务系统文件上传和互传如何做到高效又安全?
  • 【蓝桥杯】43698.最大比例
  • PageForge v2025.1.2 正式发布:打造现代化的静态站点生成工具
  • HENU~国商计科概率论复习
  • 在Linux环境下修改Anaconda的默认虚拟环境安装位置
  • Deepseek:网页版OR本地部署版本?
  • 【Linux】进程间通信(管道:匿名管道、命名管道、实战练习)
  • IDA Pro的基础指南
  • MiniQMT与xtquant:量化交易的利器
  • Leetcode—81. 搜索旋转排序数组 II【中等】
  • web前端14--flex