Net6的核心组件之中间件

What is Middleware?

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

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

中间件的三个概念(Map、Use、Run)

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

总结:

Map是接待客人(请求)的作用:告诉对应的请求,我这里可以处理 Use 是中间件,每一个Map就是一道门的守门员,门后面的功能由各个不同的中间件组成

Program

 using MiddleWare;
 ​
 var builder = WebApplication.CreateBuilder(args);
 var app = builder.Build();
 ​
 //此时只能处理localhost的请求
 app.MapGet("/", () => "Hello World!");
 ​
 //自定义中间件测试MiddleWare
 //一般不在Use里面输出内容 只在Run里面做此操作 这段代码仅仅做演示
 app.Map("/test", pilebuilder => {
     pilebuilder.Use(async (context,next) =>
    {
         //以下代码为前代码
         context.Response.ContentType = "text/html;charset=UTF-8";
         await context.Response.WriteAsync("1 start<br/>");
         //以上代码为前代码
         await next.Invoke();
         //以下代码为后代码
         await context.Response.WriteAsync("1 end<br/>");
         //以上代码为后代码
    });
     pilebuilder.Use(async (context, next) =>
    {
         //以下代码为前代码
         await context.Response.WriteAsync("2 start<br/>");
         //以上代码为前代码
         await next.Invoke();
         //以下代码为后代码
         await context.Response.WriteAsync("2 end<br/>");
         //以上代码为后代码
    });
 ​
     pilebuilder.Run(async context =>
    {
         //端点(终点)中间件
         await context.Response.WriteAsync(pw+"+Hellp MiddleWare<br/>");
 ​
    });
 });
 app.Run();
执行结果

由于这样写,代码不能复用 应该像Net6一样封装成对应的Middleware类 然后这边注入即可:

 app.UseMiddleware<TestMiddleWare>();

中间件类

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

Program

 using MiddleWare;
 ​
 var builder = WebApplication.CreateBuilder(args);
 var app = builder.Build();
 ​
 //此时只能处理localhost
 app.MapGet("/", () => "Hello World!");
 app.UseMiddleware<TestMiddleWare>();
 //自定义中间件测试MiddleWare
 //一般不在Use里面输出内容 只在Run里面做此操作 这段代码仅仅做演示
 //由于这样写,代码不能复用 应该向Net6一样封装成对应的Middleware类 然后这边注入即可
 app.Map("/test", pilebuilder => {
 //app.UseMiddleware<TestMiddleWare>(); 这个写在这里就只能对localhost/test的请求起作用
     pilebuilder.Use(async (context,next) =>
    {
         //以下代码为前代码
         context.Response.ContentType = "text/html;charset=UTF-8";
         await context.Response.WriteAsync("1 start<br/>");
         //以上代码为前代码
         await next.Invoke();
         //以下代码为后代码
         await context.Response.WriteAsync("1 end<br/>");
         //以上代码为后代码
    });
     pilebuilder.Use(async (context, next) =>
    {
         //以下代码为前代码
         await context.Response.WriteAsync("2 start<br/>");
         //以上代码为前代码
         await next.Invoke();
         //以下代码为后代码
         await context.Response.WriteAsync("2 end<br/>");
         //以上代码为后代码
    });
     pilebuilder.Run(async context =>
    {
         var pw = context.Items["content"];
         //端点(终点)中间件
         await context.Response.WriteAsync(pw+"+Hellp MiddleWare<br/>");
    });
 });
 app.Run();

TestMiddleWare:检查请求中是否有password=123的查询字符串,有的话把密码 123打出来

 namespace MiddleWare
 {
     public class TestMiddleWare
    {
         public RequestDelegate _next;
         public TestMiddleWare(RequestDelegate next )
        {
             _next=next;
        }
 ​
         public async Task InvokeAsync(HttpContext context)
        {
             var pw = context.Request.Query["password"];
             if (pw == "123")
            {
                 context.Items["content"] = "密码 123";
                 await _next(context);
            }
             else
            {
                 context.Response.StatusCode = 401;
            }
        }
 ​
    }
 }
执行结果

失败结果

总结:

以上就是中间件的基本概念和使用,中间件是Net6的核心组件,十分重要,是高级程序员所必要掌握的。求职面试中也是热点问题。

本文内容大部分都为杨中科老师《ASP.NET Core技术内幕与项目实战》一书中内容,此文只是做学习记录,如有侵权,联系立马删除。

Net6的核心组件之中间件的更多相关文章

  1. scrapy五大核心组件和中间件以及UA池和代理池

    五大核心组件的工作流程 引擎(Scrapy) 用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler) 用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. ...

  2. python爬虫---scrapy框架爬取图片,scrapy手动发送请求,发送post请求,提升爬取效率,请求传参(meta),五大核心组件,中间件

    # settings 配置 UA USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, l ...

  3. hibernate 入门([数据访问中间件] 开源框架)

    1.内容:  hibernate 也是一个经典的[数据访问中间件] 开源框架.    2.hibernate核心组件       SessionFactory[整个数据的操作]重量级组件       ...

  4. 爬虫系列---scrapy post请求、框架组件和下载中间件+boss直聘爬取

    一 Post 请求 在爬虫文件中重写父类的start_requests(self)方法 父类方法源码(Request): def start_requests(self): for url in se ...

  5. 爬虫(三)之scrapy核心组件

    01-核心组件 ·五大核心组件的工作流程: 引擎(Scrapy) 用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler) 用来接受引擎发过来的请求, 压入队列中, 并在引擎 ...

  6. scrapy之五大核心组件

    scrapy之五大核心组件 scrapy一共有五大核心组件,分别为引擎.下载器.调度器.spider(爬虫文件).管道. 爬虫文件的作用: a. 解析数据 b. 发请求 调度器: a. 队列 队列是一 ...

  7. 中间件RabbitMQ之运维篇

    一.RabbtMQ简介        RabbitMQ的官方站: http:/://www.rabbitmq.com/        rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业 ...

  8. scrapy核心组件工作流程和post请求

    一 . 五大核心组件的工作流程 引擎(Scrapy)用来处理整个系统的数据流处理, 触发事务(框架核心) 调度器(Scheduler)用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返 ...

  9. Scrapy进阶知识点总结(六)——中间件详解

    概述 查看scrapy官网的框架图,可以看出中间件处于几大主要组件之间,类似于生产流水线上的加工过程,将原料按照不同需求与功能加工成成品 其中4,5处于下载器与引擎之间的就是下载中间件,而spider ...

  10. 爬虫scrapy组件 请求传参,post请求,中间件

    post请求 在scrapy组件使用post请求需要调用 def start_requests(self): 进行传参再回到 yield scrapy.FormRequest(url=url,form ...

随机推荐

  1. python备份文件(简易)

    步骤逻辑 要备份的文件夹:source = ["/opt/containerd"] 保存备份信息的文件夹 targz_dir = "/home/backup" ...

  2. 关于MounRiver编译器配置的若干问题

    目录 一.在工程中单独设置预编译宏 二.将变量存放到指定RAM地址 三.串口打印浮点数 四.添加64位数据处理 五.使用math数学库 六.关闭仿真时自动清dataflash功能 七.配置printf ...

  3. AgilePoin规则执行

    我在写窗体规则时,明明默认值已经绑定,但是在页面加载时规则并没有起作用,导致改隐藏的没隐藏,该显示的不显示.找了半天,发现规则设置时可选择执行事件. 设置在页面加载时执行规则后,发现还是不能正确显隐组 ...

  4. Vue中的样式作用域

    介绍对于Vue样式作用域的介绍 对于所有组件中的Css都是通用的 在未指定作用域之前 在A组件中定义的 {.h1{color:red}} 同样会在b组件中生效 如果在B组件中也定义了 h1元素. 虽然 ...

  5. OS-lab4

    OS-lab4 系统调用 系统调用的流程 按照上述的流程逐个分析. user/syscall_lib.c 这个文件位于user文件夹下,也就是用户程序可以调用的函数,相当于操作系统提供给用户程序的一些 ...

  6. win10系统IE浏览器打不开 点击无反应 解决办法

    打开左下角开始菜单 步骤阅读 2 点击右边的Cortana,在下面的输入框中输入:regedit,等待它自动搜索出来后,以管理员身份打开这个注册表编辑器:当然熟悉电脑的同学可以直接打开运行----re ...

  7. mysql中的InnoDB和MyISAM

    InnoDB:支持事务,支持表级锁,行级锁,支持外键,是非聚集索引. MyISAM:不支持事务,支持表级锁,不支持外键,聚集索引. 聚集索引和非聚集索引的区别:InnoDB是聚集索引,使用B+Tree ...

  8. 网络协议及osi模型

    osi模型:由高到底 应用层:最高一层,是用户与网络的接口 表示层: 会话层: 传输层:作用是为上层协议提供端到端的可靠和透明的数据传输服务 网络层: 数据链路层: 物理层:它利用传输介质为数据链路层 ...

  9. iOS Programing

    ARC 1. ARC - Automatic Reference Counting 办公室照明原理 2. 函数release立即释放,autorelease进入autoreleasepool里 3. ...

  10. ES-增删改查

    写作目的 供想了解ES数据操作的伙伴学习ES的CRUD操作. 测试环境 ES7.8.1 postman 创建索引库 // PUT请求 localhost:9200/test_alert { " ...