聊聊 ASP.NET Core 中间件(三):如何创建自己的中间件?

image

前言

本质上,中间件类也是一个普通的 .NET 类,它不需要继承任何父类或者实现任何接口。

但是有几个约定:

  1. 需要有一个构造方法
  2. 构造方法至少要有一个 RequestDelegate 类型的参数,用来指向下一个中间件。
  3. 需要定义一个名字为 Invoke 或 InvokeAsync 的方法
  4. 此方法中至少有一个 HttpContext 类型的参数
  5. 此个方法的返回值必须是 Task 类型

只要遵守以上这些约定,就可以轻松创建自己的中间件。

以下是一个 Step By Step 例子。

Step By Step 步骤

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

  2. 定义一个用于中间件的实体类

    public class CheckAndParsingMiddlewareModel
    {public int i { get; set; }public int j { get; set; }
    }
    
  3. 定义一个中间件类 CheckAndParsingMiddleware,留意注释

    using System.Text.Json;
    using System.Text;/// <summary>
    /// 自定义中间类,要求如注释的 1~5 点
    /// </summary>
    public class CheckAndParsingMiddleware
    {private readonly RequestDelegate next;// 1. 需要有一个构造方法// 2. 构造方法需要有一个 RequestDelegate 类型的参数,用于指向下一个中间件public CheckAndParsingMiddleware(RequestDelegate next){this.next = next;}// 3. 需要有一个名为 Invoke 或 InvokeAsync 的方法// 4. 此方法至少要有一个 HttpContext 类型参数// 5. 此方法的返回值必须是 Task 类型public async Task InvokeAsync(HttpContext context){string pwd = context.Request.Query["password"];if (pwd == "123"){if (context.Request.HasJsonContentType()){// 解析 Body 参数的值var reqStream = context.Request.BodyReader.AsStream();var jsonObj = JsonSerializer.Deserialize<CheckAndParsingMiddlewareModel>(reqStream);// 将数据存在Items中// HttpContext.Items 在同一个请求中是共享的,可以用它在多个中间件之间来传递数据context.Items["BodyJson"] = jsonObj; }// 把请求转给下一个中间件await next(context); }else{context.Response.StatusCode = 401;}}
    }
    
  4. 打开 Program.cs,编写使用自定义的中间件的代码,如:

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();app.Map("/testForCustomMiddleware", async appbuild => { // 使用自定义的中间件appbuild.UseMiddleware<CheckAndParsingMiddleware>();// 执行appbuild.Run(async ctx => {ctx.Response.ContentType = "text/html";ctx.Response.StatusCode = 200;var jsonObj = (CheckAndParsingMiddlewareModel)ctx.Items["BodyJson"];int i = jsonObj.i;int j = jsonObj.j;await ctx.Response.WriteAsync($"{i}+{j}={i+j}");});
    });app.Run();
    
  5. 其它:解析 Body 参数值的方法

    // 方法 1
    var reqStream = context.Request.BodyReader.AsStream();
    var jsonObj = JsonSerializer.Deserialize<CheckAndParsingMiddlewareModel>(reqStream);// 方法 2
    Stream reqStream = context.Request.Body;
    byte[] buffer = new byte[context.Request.ContentLength!.Value];
    await reqStream.ReadAsync(buffer, 0, buffer.Length);
    var reqStr = Encoding.UTF8.GetString(buffer);
    dynamic jsonObj = JsonSerializer.Deserialize<dynamic>(reqStr)!;
    

扩展

中间件类的构造方法和 Invoke(或 InvokeAsync)方法还可以定义其他参数,其他参数会通过依赖注入自动赋值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/7791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式linux学习第一天

参考正点原子Linux开发文档。记录下知识点。 Shell 基本操作 前面我们说 Shell 就是“敲命令”&#xff0c;那么既然是命令&#xff0c;那肯定是有格式的&#xff0c;Shell 命令的格式 如下&#xff1a; command -options [argument] command: Shell 命令名称。 options&…

雷军-2022.8小米创业思考-6-互联网七字诀之专注:有所为,有所不为;克制贪婪,少就是多;一次解决一个最迫切的需求

第六章 互联网七字诀 专注、极致、口碑、快&#xff0c;这就是我总结的互联网七字诀&#xff0c;也是我对互联网思维的高度概括。 专注 从商业角度看&#xff0c;专注就是要“把鸡蛋尽量放在一个篮子里”。这听起来似乎有些不合理&#xff0c;大家的第一反应可能是“风险会不会…

JUC-synchronized练习-交替打印ABC

今天来练习一下synchronized 简单来利用synchronized实现一个字符串的交替打印 主要的实现设置一个全局的变量state&#xff0c;线程执行通过不断累加state&#xff0c;根据state对三取余的结果来判断该线程是否继续执行还是进入等待。并通过synchronized锁住一个共享变量loc…

线程池会遇到的刁钻问题(下)

文章目录 如何处理线程池中的异常&#xff1f;在并发编程中&#xff0c;线程池和锁有什么关系&#xff1f;如何实现一个可以动态调整大小的线程池&#xff1f;方法一&#xff1a;扩展 ThreadPoolExecutor方法二&#xff1a;使用 ScheduledExecutorService 如何确保线程池中的任…

Fastapi中怎么一次性运行多个Scrapy爬虫

运行Scrapy爬虫很简单&#xff0c;直接"Scrapy crawl 爬虫名称"即可。但是我们如果想在Fastapi中通过接口的方式一次性运行多个爬虫。那该怎么实现&#xff1f; 假如在scrapy下面的spiders里面写了许多爬虫文件&#xff0c;你可以在spiders的__init__.py文件中&…

js 图片渐变

1. 点击图片&#xff0c;使其渐变为另一张图片 通过定义keyframes来创建一个淡入淡出的动画效果。当图片被点击时&#xff0c;先添加淡出动画使图片透明度从0渐变到1&#xff0c;然后在1秒后切换图片源并添加淡入动画使新图片透明度从0渐变到1&#xff0c;实现图片渐变效果。 …

电路板第一次调试注意事项

电路板第一次调试注意事项 调板经验其他人的经验一、上电前检查1、目测检查2、电源短路检查3、连线检查4、元器件安装检查 二、通电后检测1、通电观察2、静态调试3、动态调试 调板经验 1.打开原理图 PCB&#xff0c;熟悉一遍。 2.拿到板&#xff0c;找到输入正负极&#xff0…

VUE的回调函数,使用this变量undefined,怎么办

由于预订的抓拍方案无法令人满意&#xff0c;于是又回到了直接在WEB抓拍的方案。这个我信心满满&#xff0c;因为之前的代码已经验证过了。 验证是通过的&#xff0c;想法是简单的&#xff0c;现实是不通的。我一点抓拍按钮&#xff0c;没反应啊。这是怎么回事呢&#xff1f;于…

自动化机器学习——贝叶斯优化

自动化机器学习——贝叶斯优化 贝叶斯优化是一种通过贝叶斯公式推断出目标函数的后验概率分布&#xff0c;从而在优化过程中不断地利用已有信息来寻找最优解的方法。在贝叶斯优化中&#xff0c;有两个关键步骤&#xff1a;统一建模和获得函数的优化。 1. 统一建模 在贝叶斯优…

.双链表.

题目&#xff1a; 实现一个双链表&#xff0c;双链表初始为空&#xff0c;支持 55 种操作&#xff1a; 在最左侧插入一个数&#xff1b;在最右侧插入一个数&#xff1b;将第 k&#x1d458; 个插入的数删除&#xff1b;在第 k&#x1d458; 个插入的数左侧插入一个数&#xf…

MYSQL-使用事务保证数据完整性

什么是事务&#xff1f; 事务&#xff08;Transaction&#xff09;是作为单个逻辑工作单元执行的一系列操作 多个操作作为一个整体向系统提交&#xff0c;要么都执行&#xff0c;要么都不执行 事务的特性&#xff1a; 事务必须具备以下四种属性&#xff0c;简称ACID属性 1、…

新型中医揿针如何降血糖呢?

点击文末领取揿针的视频教程跟直播讲解 “新型针贴”专用揿针是为“埋针疗法”特制治的一种特殊针具&#xff0c;它是古代针刺留针方法的发展。具体来说&#xff0c;它是将特制针具刺入皮内&#xff0c;固定后留置一定时间&#xff0c;利用其持续微弱的刺激作用来治疗疾病的一…

做抖音小店需要注意什么?这几点很多人不知道,看完防踩坑

大家好&#xff0c;我是电商笨笨熊 抖音小店虽然推出了一段时间&#xff0c;但是依旧有新手玩家陆陆续续加入其中&#xff1b; 对于很多新手来说&#xff0c;只看到了其中红利&#xff0c;但却没有看到其中包含的一些运营小细节&#xff0c;且这些细节决定你店铺未来发展&…

现代城市化生活下,很多人有高薪,但是工作压力大,幸福度和自由度不一定高,从社会发展和哲学的角度来解读一下

在现代城市化生活中&#xff0c;高薪与工作压力、幸福度和自由度的关系&#xff0c;确实是一个值得从社会发展和哲学角度深入探讨的话题。 从社会发展角度看 经济驱动&#xff1a;随着社会的快速发展&#xff0c;经济成为推动社会进步的重要力量。人们为了追求更高的生活质量…

u段麦克风方案无线技术的特点与优势

UHF无线麦克风相比其他无线技术具有多个优势&#xff1a; 低成本和高效率&#xff1a;UHF无线麦克风系统可以实现低成本的解决方案&#xff0c;特别是在短距离应用中&#xff0c;如教室中的助听设备。这种系统不仅成本较低&#xff0c;还能提供与电话质量相近的声音质量&#…

【redis】Redis数据类型(四)Set类型

目录 Set类型介绍使用场景 Set类型数据结构set的单个元素的添加过程IntSet哈希表内存结构 常用命令SADD示例 SREM示例 SMEMBERS示例 SISMEMBER示例 SCARD示例 SMOVE示例 SPOP示例 SRANDMEMBER示例 SINTER示例 SINTERSTORE示例 SUNION示例 SUNIONSTORE示例 SDIFF示例 SDIFFSTORE…

常用邮箱汇总

01. 临时邮箱 24小时邮箱&#xff1a;http://24mail.chacuo.net60分钟邮箱&#xff1a;https://www.guerrillamail.com/zh/10 分钟邮箱&#xff1a;https://linshiyouxiang.net/10 分钟邮箱&#xff1a;https://temp-mail.org/zh/10 分钟邮箱&#xff1a;https://10minutemail…

webrtc应用举例

WebRTC&#xff08;Web Real-Time Communication&#xff09;是一种用于在Web浏览器和移动应用程序之间进行实时通信的开放标准。以下是一些WebRTC应用的例子&#xff1a; 1. **WebRTC电话**&#xff1a;用户可以通过Web浏览器进行点对点的音频和视频通话&#xff0c;无需安装…

每日一题(PTAL2):列车调度--贪心+二分

选择去维护一个最小区间 代码1&#xff1a; #include<bits/stdc.h> using namespace std; int main() {int n;cin>>n;int num;vector <int> v;int res0;for(int i0;i<n;i){cin>>num;int locv.size();int left0;int rightv.size()-1;while(left<…

c语言之枚举

枚举是将一个变量的可能的值都列出来&#xff0c;但是对应的值只能是其中的一个。 枚举创建的方式 enum 枚举类型名&#xff08;值1&#xff0c;值2&#xff0c;值3&#xff0c;值n&#xff09; 如何定义枚举变量 enum 枚举类型 变量名 示例代码如下 #include<stdio.h…