聊聊 ASP.NET Core 中间件(一):一个简单的中间件例子

news/2024/9/20 7:02:24/ 标签: 中间件, 经验分享, c#, asp.net core

image

前言:什么是中间件

服务器在收到 HTTP 请求后会对用户的请求进行一系列的处理,比如检查请求的身份验证信息、处理请求报文头、检查是否存在对应的服务器端响应缓存、找到和请求对应的控制器类中的操作方法等,当控制器类中的操作方法执行完成后,服务器也会对响应进行一系列的处理,比如保存响应缓存、设置缓存报文头、设置 CORS 报文头、压缩响应内容等。这些就是通过中间件进行处理的。

广义上来讲,中间件指的是系统软件和应用软件之间连接的软件,以便于软件之间的沟通,比如 Web 服务器、Redis 服务器等都可以称作中间件

狭义上来讲,ASP.NET Core 中的中间件则指 ASP.NET Core 中的一个组件。

每个中间件由前逻辑、next、后逻辑3部分组成,前逻辑为第一段要执行的逻辑代码,next为指向下一个中间件的调用,后逻辑为从下一个中间件返回所执行的逻辑代码。

每个 HTTP 请求都要经历一系列中间件的处理,每个中间件对请求进行特定的处理后,再将其转到下一个中间件,最终的业务逻辑代码执行完成后,响应的内容也会按照请求处理的相反顺序进行处理,然后形成 HTTP 响应报文返回给客户端。

中间件组成一个管道(pipeline),整个 ASP.NET Core 的执行过程就是 HTTP 请求和响应按照中间件组装的顺序在中间件之间流转的过程。

中间件有点类似过过滤器,但中间件处理更底层,更快被处理

中间件有 3 重要的概念:Map、Use 和 Run。

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

也就是说,Map 是用来引入请求的,请求来到管道之后,由组成管道的多个 Use 负责对请求进行预处理及请求处理完成后的扫尾工作,Run 负责主要的业务规则。

下面通过一个简单的 Step By Step 例子来直观地感受中间件的魅力。

Step By Step 步骤

  1. 创建一个空 ASP.NET Core webapi 项目

  2. 打开 Program.cs,编写以下代码,留意注释

    c#">var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();//Map 引用请求,一个管道
    app.Map("/test", async appbuilder => {//Use 中间件1appbuilder.Use(async (context, next) => {//前逻辑context.Response.ContentType = "text/html";await context.Response.WriteAsync("1  Start<br/>");//执行下一个中间件await next.Invoke(); //后逻辑await context.Response.WriteAsync("1  End<br/>");});//Use 中间件2appbuilder.Use(async (context, next) => {//前逻辑await context.Response.WriteAsync("2  Start<br/>");//执行最终业务操作方法,因为没有下一个中间件await next.Invoke(); //后逻辑await context.Response.WriteAsync("2  End<br/>");});//Run 最终业务操作方法appbuilder.Run(async ctx => {// 如果在一个中间件中使用 ctx.Response.WriteAsync 向客户端发送响应,// 就不能再执行 next.Invoke 把请求转到其他中间件了// 因为其他中间件中有可能对 Response 进行了更改,比如修改响应状态码、修改报文头或者向响应报文中写入其他数据,// 这样就会造成响应报文体被损坏的问题// 所以这里在向报文体中写入内容后,又执行 next.Invoke 是不推荐的行为// 只是为了演示而已await ctx.Response.WriteAsync("hello middleware <br/>");});
    });app.Run();
    
  3. 运行,打印出执行顺序:

    1. 中间件1 - 前逻辑
    2. 中间件2 - 前逻辑
    3. 最终业务操作方法
    4. 中间件2 - 后逻辑
    5. 中间件1 - 后逻辑
    6. 输出

总结

  1. 不在 Map 定义的管道中的中间件代码如: app.UseHttpsRedirection();),会默认处理所有的请求
  2. 中间件是按照顺序执行的,因此中间件组装的顺序非常重要

http://www.ppmy.cn/news/1451964.html

相关文章

十大排序算法之——堆排序算法(Java实现)及思路讲解

堆排序是一种非常有效的排序算法&#xff0c;它利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构&#xff0c;并同时满足堆积的性质&#xff1a;即子节点的键值或索引总是小于&#xff08;或者大于&#xff09;它的父节点。堆排序可以分为两个主要部分&a…

手搓堆(C语言)

Heap.h #pragma once#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> #include <string.h> typedef int HPDataType; typedef struct Heap {HPDataType* a;int size;int capacity; }Heap;//初始化 void Heap…

深入理解 LinkedList 及底层源码分析

LinkedList 是基于链表结构的一种 List&#xff0c;在分析 LinkedList 源码前我们先对对链表结构做一个简单的了解。 一、链表的概念 链表是由一系列非连续的节点组成的存储结构&#xff0c;简单分下类的话&#xff0c;链表又分为_单向链表和双向链表&#xff0c;而单向 / 双…

nginx--第三方模块安装上传下载服务

第三方模块安装 准备 cd /usr/local/src/ yum install git -y git clone https://github.com/openresty/echo-nginx-module.git cd nginx-1.24.0 yum -y install perl-devel perl-ExtUtils-Embed zlib-devel gcc-c libtool openssl openssl-devel 编译安装 ./configure \--p…

SQL注入漏洞扫描---sqlmap

what SQLMap是一款先进的自动执行SQL注入的审计工具。当给定一个URL时&#xff0c;SQLMap会执行以下操作&#xff1a; 判断可注入的参数。判断可以用哪种SQL注入技术来注入。识别出目标使用哪种数据库。根据用户的选择&#xff0c;读取哪些数据库中的数据。 更详细语法请参考…

C语言:指针详解(3)

目录 一、字符指针 二、数组指针 1.数组指针的定义 2.数组指针的初始化 3. 二维数组传参的本质 三、函数指针 1.函数指针的创建 2.函数指针的使用 3.有趣的代码(1) 4.有趣的代码(2) 四、typedef关键字 1.typedef的使用方法 2.typedef和#define的区别 五、函数指针…

Ubuntu22.04安装Nvidia 550驱动和CUDA toolkit 12.4.1

1. 安装显卡驱动550版本&#xff1a; wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt-get update sudo apt-get -y install cuda-drivers 命令来源于&…

牛客Xorto

Xorto 题目描述 给定一个长度为n的整数数组&#xff0c;问有多少对互不重叠的非空区间&#xff0c;使得两个区间内的数的异或和为0。 输入描述: 第一行一个数n表示数组长度&#xff1b; 第二行n个整数表示数组&#xff1b; 1<n<1000,0<数组元素<100000。 输出…

【Android学习】简易计算器的实现

1.项目基础目录 新增dimens.xml 用于控制全部按钮的尺寸。图片资源放在drawable中。 另外 themes.xml中原来的 <style name"Theme.Learn" parent"Theme.MaterialComponents.DayNight.DarkActionBar">变为了&#xff0c;加上后可针对button中增加图片…

Angular中的管道(Pipe)

Angular中的管道(Pipe) 文章目录 Angular中的管道(Pipe)前言一、内置管道1. date管道格式化日期2. currency管道格式化货币3. uppercase和lowercase管道转换字符串大小写4. 小数位数5. JavaScript 对象序列化6. slice7. 管道链 二、自定义管道 前言 Angular中的管道&#xff0…

[蓝桥杯2024]-PWN:ezheap解析(堆glibc2.31,glibc2.31下的double free)

查看保护 查看ida 大致就是只能创建0x60大小的堆块&#xff0c;并且uaf只能利用一次 完整exp&#xff1a; from pwn import* #context(log_leveldebug) pprocess(./ezheap2.31)def alloc(content):p.sendlineafter(b4.exit,b1)p.send(content) def free(index):p.sendlineaft…

Qt扫盲-Qt D-Bus概述

Qt D-Bus概述 一、概述二、总线三、相关概念1. 消息2. 服务名称3. 对象的路径4. 接口5. 备忘单 四、调试五、使用Qt D-Bus 适配器1. 在 D-Bus 适配器中声明槽函数1. 异步槽2. 只输入槽3. 输入输出槽4. 自动回复5. 延迟回复 一、概述 D-Bus是一种进程间通信(IPC)和远程过程调用…

ubuntu Qt打包

在Linux 下如何打包免安装的QT程序&#xff1f;-CSDN博客 [教程][Ubuntu][Qt]将Qt程序打包成deb文件&#xff0c;发布、安装及使用_qt生成deb-CSDN博客

前端关于location的方法以属性

目录 一、location是用来做什么的&#xff1f; 二、location的属性和方法能实现什么功能&#xff1f; 功能一&#xff1a;获取当前页面的URL信息 功能二&#xff1a;页面跳转 location.assign() 附&#xff1a;其他页面跳转的方法 1.location.href 2.window.open() …

QAnything知识库问答系统离线部署(LLM+RAG)

一、QAnything介绍 &#xff08;一&#xff09;简介 QAnything 是网易有道开源的一个问答系统框架&#xff0c;支持私有化部署和SaaS服务两种调用形式。它能够支持多种格式的文件或数据库&#xff0c;提供准确、快速和可靠的问答体验。目前已支持的文件格式包括PDF、Word、PP…

微信小程序开发:深入实现地图导航功能【含代码示例】

微信小程序开发&#xff1a;深入实现地图导航功能【含代码示例】 一、引言二、准备工作三、集成地图SDK四、实现地图显示五、添加标记点和路线 一、引言 微信小程序作为一种轻量级的应用程序&#xff0c;凭借其无需安装、即用即走的特点&#xff0c;迅速在移动应用市场中占据了…

【软件工程】概要设计

目录 前言软件设计简介概要设计模块化模块化的评价耦合内聚 面向对象设计原则Liskov替换原则&#xff08;LSP&#xff09;开放-封闭原则&#xff08;OCP&#xff09;单一职责原则&#xff08;SRP&#xff09;接口隔离原则&#xff08;ISP&#xff09;依赖倒置原则&#xff08;D…

关于springboot内置tomcat最大请求数配置的一些问题

前言 springboot内置了tomcat。那么一个springboot web应用&#xff0c;最大的请求链接数是多少呢&#xff1f;很早以前就知道这个是有个配置&#xff0c;需要的时候&#xff0c;百度一下即可。但&#xff0c;事实并非如此&#xff0c;有几个问题我想大多数人还真不知道。比如…

基于Sping Boot集成的websocket实现聊天室

Spring Boot整合WebSocket实现聊天室 Spring Boot 提供了 Websocket 组件 spring-boot-starter-websocket&#xff0c;用来支持在 Spring Boot环境下对Websocket 的使用。 下面我们就以多人在线聊天室为例&#xff0c;演示 Spring Boot 是如何整合Websocket 实现服务端消息推…

python(abi)是什么,有什么作用呢

python(abi) 是一个特殊的提供项&#xff0c;用于指定软件包所支持的Python ABI&#xff08;Application Binary Interface&#xff09;版本。 Python ABI是一种约定&#xff0c;用于定义Python解释器和扩展模块之间的二进制接口。它确保了不同版本的Python解释器和扩展模块之…