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

news2024/11/28 2:49:20

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.coloradmin.cn/o/1650341.html

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

相关文章

交易复盘-20240507

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 蔚蓝生物 (5)|[9:25]|[36187万]|4.86 百合花…

STM32F10x移植FreeRTOS

一、获取FreeRTOS源码 &#xff08;1&#xff09;登录FreeRTOS官网&#xff1a;www.freertos.org&#xff0c;下载第一个压缩包 &#xff08;2&#xff09;通过GitHub网站&#xff1a;github.com/FreeRTOS/FreeRTOS下载&#xff0c;由于该网站服务器在国外&#xff0c;所以访问…

28.leetcode---前K个高频单词(Java版)

题目链接: https://leetcode.cn/problems/top-k-frequent-words/description/ 题解: 代码: 测试:

巨控GRM561/562/563/564Q杀菌信息远程监控

摘要 通过程序编写、手机APP画面制作等运行系统&#xff0c;实现电脑及手机APP显示的历史曲线画面和数据图形化的实时性。 不仅流程效率提升90%以上&#xff0c;同时为杀菌生产提供有利的质量保障&#xff0c;还有效规避因触屏及内存卡的突发异常导致历史数据的丢失&#xff0…

强大的禄得可转债自定义因子轮动系统完成,可转债三低为例子

经过几天的测试终于完成了可转债自定义因子轮动&#xff0c;超过1000行的源代码 我提供了服务器的数据支持自动api下载&#xff0c;我给大家维护数据 网页 http://120.78.132.143:8023/ 录得数据支持http://120.78.132.143:8023/lude_data_app api数据支持&#xff0c;我提供…

杭州恒生面试,社招,3年经验

你好&#xff0c;我是田哥 一位朋友节前去恒生面试&#xff0c;其实面试问题大部分都是八股文&#xff0c;但由于自己平时工作比较忙&#xff0c;完全没有时间没有精力去看八股文&#xff0c;导致面试结果不太理想&#xff0c;HR说节后通知面试结果&#xff08;估计是凉了&…

传统汽车空调系统工作原理

1.首先讲一个概念 液体变成气体&#xff1a;吸热 气体变成液体&#xff1a;放热 2.在汽车空调系统中热量的传递的介质不是水&#xff0c;而是氟利昂&#xff0c;简称&#xff1a;“氟”。 3.传统式汽车空调结构如下 该三个部件位于车头进气口位置 该部位位于汽车驾驶车厢前方…

常见的容器技术有哪些

容器技术是一种轻量级的软件封装方式&#xff0c;它将软件代码及其依赖项打包在一起&#xff0c;这样应用可以在任何支持容器的系统上无缝运行。它允许应用程序及其依赖项在一个隔离的环境中运行&#xff0c;这个环境被称为容器。容器技术有助于提高应用程序的可移植性、一致性…

Vue3专栏项目 -- 一、第一个页面(上)

一、ColumnList 组件&#xff08;专栏列表组件&#xff09;编码&#xff1a; 该组件要接收一个数组&#xff0c;数组中是一个个专栏数据&#xff0c;数据中包括id、title、avator、description。所以我们定义一个泛型&#xff0c;泛型为id为number类型title为string类型如下这…

初识C++ · 类和对象(下)

目录 1 再谈构造函数 2 类中的隐式类型转换 3 Static成员 4 友元和内部类 5 匿名对象 6 编译器的一些优化 1 再谈构造函数 先看一段代码&#xff1a; class Date { public :Date(int year, int month, int day){_year year;_month month;_day day;} private:int _ye…

Redis之Linux下的安装配置

Redis之Linux下的安装配置 Redis下载 Linux下下载源码安装配置 方式一 官网下载&#xff1a;https://redis.io/download ​ 其他版本下载&#xff1a;https://download.redis.io/releases/ 方式二&#xff08;推荐&#xff09; GitHub下载&#xff1a;https://github.com/r…

基于ambari hdp的kafka用户授权读写权限

基于ambari hdp的kafka用户授权读写权限 版本Kafka 2.0.0添加自定义配置修改admin密码重启kafka授权读取授权写入有效通配符部分举例 版本Kafka 2.0.0 添加自定义配置 authorizer.class.name kafka.security.auth.SimpleAclAuthorizer super.users User:admin allow.everyo…

【强训笔记】day13

NO.1 代码实现&#xff1a; #include <iostream>#include<string>using namespace std;int n,k,t; string s;int func() {int ret0;for(int i0;i<n;i){char chs[i];if(chL) ret-1;else{if(i-1>0&&i-2>0&&s[i-1]W&&s[i-2]W) retk…

Android 官网Ota介绍

构建 OTA 软件包 | Android 开源项目 | Android Open Source Project

太阳能光伏在生活中的三大作用

随着现在太阳能光伏的逐步发展&#xff0c;太阳能光伏已经越来越走近人们的生活&#xff0c;小编带大家盘点一下光伏在生活中的应用 一、发电 光伏的最初应用就是用来发电&#xff0c;以替代传统的化石燃料发电方式。光伏发电可以从根本上解决当今社会面临的能源短缺问题&…

我的板子为什么测不了损耗

高速先生成员--周伟 最近我们珠海高速实验室正式对外开放了&#xff0c;我们也同步推出了关于高速信号测试、高速仪器的一些视频。 大家知道我们有仪器后&#xff0c;很多热心的小伙伴们就以为我们开挂了&#xff0c;什么都能测&#xff0c;然后就会来咨询我们&#xff0c;很多…

申请免费一年期的https证书

现在https证书的普及度还是比较高的&#xff0c;大众对于https证书的需求度也日益提升。针对于一些个人用户或是企业而言&#xff0c;实现网站的https访问已经成为了一种标配。 当前的免费证书&#xff1a; 截止到2024年为止&#xff0c;基本所有平台都停止了对于一年期免费S…

Windows环境编译 VVenC 源码生成 Visual Studio 工程

VVenC介绍 Fraunhofer通用视频编码器(VVenC)的开发是为了提供一种公开可用的、快速和有效的VVC编码器实现。VVenC软件基于VTM&#xff0c;其优化包括软件重新设计以减轻性能瓶颈、广泛的SIMD优化、改进的编码器搜索算法和基本的多线程支持以利用并行。此外&#xff0c;VVenC支…

Python运维-日志记录、FTP、邮件提醒

本章目录如下&#xff1a; 五、日志记录 5.1、日志模块简介 5.2、logging模块的配置与使用 六、搭建FTP服务器与客户端 6.1、FTP服务器模式 6.2、搭建服务器 6.3、编写FTP客户端程序 七、邮件提醒 7.1、发送邮件 7.2、接收邮件 7.3、实例&#xff1a;将报警信息实时…

python实验三 实现UDP协议、TCP协议进行服务器端与客户端的交互

实验三 实验题目 1、请利用生成器构造一下求阶乘的函数Factorial()&#xff0c;定义一个函数m()&#xff0c;在m()中调用生成器Factorial()生成小于100的阶乘序列存入集合s中&#xff0c;输出s。 【代码】 def factorial():n1f1while 1:​ f * n​ yield (f)​ n1…