【ASP.NET Core 基础知识】--中间件--创建自定义中间件

一、为什么需要自定义中间件

自定义中间件在ASP.NET Core中的应用主要有以下几个原因:

  1. 满足特定需求: 默认情况下,ASP.NET Core提供了许多内置的中间件来处理常见的任务,如身份验证、授权、静态文件服务等。然而,某些项目可能有特定的需求,需要定制化的处理流程,这时就需要创建自定义中间件以满足项目的特殊要求。
  2. 增加业务逻辑: 自定义中间件允许开发人员向请求处理流程中添加业务逻辑。这对于执行与应用程序的核心功能相关的任务非常有用,例如日志记录、性能监控、请求转换等。通过自定义中间件,开发人员可以灵活地将业务逻辑集成到请求处理管道中。
  3. 解耦和模块化: 自定义中间件有助于将应用程序的不同部分解耦,使代码更具模块化和可维护性。每个中间件可以专注于特定的任务,这样代码的组织结构更清晰,便于理解和维护。
  4. 性能优化: 自定义中间件可以用于执行性能优化任务,例如缓存、压缩、请求重定向等。通过在请求处理流程中插入自定义中间件,可以更好地控制和优化应用程序的性能。
  5. 适应特定场景: 不同的应用场景可能需要不同类型的中间件。通过创建自定义中间件,开发人员可以根据应用的特定需求,灵活地调整和配置中间件,以适应不同的使用场景。

自定义中间件为开发人员提供了更大的灵活性和控制权,使他们能够更好地定制和优化ASP.NET Core应用程序的请求处理流程,满足特定的业务和性能需求。

二、创建自定义中间件的基本步骤

创建自定义中间件涉及以下基本步骤:

  1. 创建一个类: 创建一个类来实现你的中间件。这个类通常需要包含一个构造函数以及一个名为InvokeInvokeAsync等的方法,用于处理请求。
    public class CustomMiddleware
    {private readonly RequestDelegate _next;public CustomMiddleware(RequestDelegate next){_next = next;}public async Task InvokeAsync(HttpContext context){// 中间件逻辑处理await _next(context);}
    }
    
  2. 添加中间件的基本结构: 在中间件类中,你需要编写逻辑来处理请求。可以在Invoke方法中执行你的自定义逻辑,然后通过_next字段调用下一个中间件。
  3. 注册中间件:Startup.cs文件的Configure方法中,使用UseMiddlewareUse方法将中间件添加到请求处理管道中。确保注册中间件的顺序正确,因为中间件的执行顺序很重要。
    public void Configure(IApplicationBuilder app)
    {// 其他中间件app.UseMiddleware<CustomMiddleware>();// 或者使用 app.Use<CustomMiddleware>();// 其他中间件
    }
    
  4. 中间件的执行流程: 确保理解中间件的执行流程。当请求到达时,每个中间件按照注册的顺序依次执行,然后请求通过管道传递给下一个中间件,直到最终的处理程序。
  5. 配置中间件: 如果中间件需要配置选项,可以通过构造函数参数或其他方式将配置传递给中间件。这允许你在Startup.cs中配置中间件的行为。
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {// 其他中间件app.UseMiddleware<CustomMiddleware>(/* configuration options */);// 其他中间件
    }
    
  6. 测试中间件: 最后,确保测试你的中间件。创建单元测试和集成测试,验证中间件在不同场景下的正确性和可靠性。

三、中间件的参数和上下文对象

3.1 解释中间件的参数

ASP.NET Core 中间件的 InvokeInvokeAsync 方法通常接受一个 HttpContext 参数,该参数提供了关于当前请求和响应的信息。此外,中间件的构造函数也可以接受其他服务或选项,以实现更多的定制和灵活性。

  1. HttpContext 参数:
    • HttpContext 包含了有关当前请求和响应的信息,如请求路径、请求方法、请求头、查询参数、响应状态等。
    • 可以使用 HttpContext 提供的方法来访问请求和响应的内容,以及执行与中间件逻辑相关的操作。
    public async Task InvokeAsync(HttpContext context)
    {// 使用 context 处理请求和响应
    }
    
  2. 构造函数参数:
    • 构造函数可以接受其他服务作为参数,这些服务是通过 ASP.NET Core 依赖注入系统提供的。通过依赖注入,可以在中间件中使用其他组件,如数据库上下文、日志记录器等。
    public class CustomMiddleware
    {private readonly RequestDelegate _next;private readonly ILogger<CustomMiddleware> _logger;public CustomMiddleware(RequestDelegate next, ILogger<CustomMiddleware> logger){_next = next;_logger = logger;}// ...
    }
    
  3. 配置选项:
    • 如果中间件需要配置选项,可以通过构造函数参数传递配置信息。这样,中间件的行为可以在 Startup.cs 中进行配置。
    public class CustomMiddlewareOptions
    {public string OptionValue { get; set; }
    }public class CustomMiddleware
    {private readonly RequestDelegate _next;private readonly CustomMiddlewareOptions _options;public CustomMiddleware(RequestDelegate next, IOptions<CustomMiddlewareOptions> options){_next = next;_options = options.Value;}// ...
    }
    
3.2 上下文对象的作用和使用方法

HttpContext 是 ASP.NET Core 中间件中的关键对象,它提供了有关当前请求和响应的信息,允许中间件与请求处理流程进行交互。以下是 HttpContext 的主要作用和使用方法:

  1. 请求信息的获取:

    • 通过 HttpContext.Request 属性,可以获取有关当前请求的详细信息,如路径、方法、协议、头部、查询参数等。
    public async Task InvokeAsync(HttpContext context)
    {string path = context.Request.Path;string method = context.Request.Method;// 其他请求信息的获取
    }
    
  2. 响应信息的设置:

    • 通过 HttpContext.Response 属性,可以设置有关响应的信息,如状态码、头部、内容类型等。
    public async Task InvokeAsync(HttpContext context)
    {context.Response.StatusCode = 200;context.Response.ContentType = "text/plain";// 其他响应信息的设置
    }
    
  3. 处理请求和响应内容:

    • 通过 HttpContext.Request.BodyHttpContext.Response.Body 属性,可以访问请求和响应的主体内容,允许中间件对其进行读取或写入。
    public async Task InvokeAsync(HttpContext context)
    {using (StreamReader reader = new StreamReader(context.Request.Body)){string requestBody = await reader.ReadToEnd();// 处理请求主体内容}// 处理响应主体内容await context.Response.WriteAsync("Hello, World!");
    }
    
  4. 用户认证和授权信息:

    • HttpContext.User 属性包含有关用户的认证和授权信息,允许中间件根据用户的角色和声明执行相应的逻辑。
    public async Task InvokeAsync(HttpContext context)
    {ClaimsPrincipal user = context.User;// 处理用户认证和授权信息
    }
    
  5. 重定向和路由:

    • 通过 HttpContext.Response.Redirect 方法,可以执行重定向操作。而通过 HttpContext.GetRouteData 方法,可以获取有关当前路由的信息。
    public async Task InvokeAsync(HttpContext context)
    {// 执行重定向context.Response.Redirect("/newpath");// 获取路由信息RouteData routeData = context.GetRouteData();// 处理路由信息
    }
    
  6. 上下文的传递:

    • HttpContext.Items 属性允许中间件在请求处理流程中传递数据。这对于在中间件之间共享信息非常有用。
    public async Task InvokeAsync(HttpContext context)
    {context.Items["Key"] = "Value";// 在中间件之间传递数据
    }
    

通过充分利用 HttpContext 对象的这些功能,中间件可以与请求处理管道中的其他组件进行交互,执行特定的逻辑,并对请求和响应进行处理。

四、示例:记录请求日志的中间件

以下是一个简单的示例,展示如何创建一个记录请求日志的自定义中间件。该中间件将请求的路径和时间戳记录到控制台,并继续将请求传递给下一个中间件或处理程序。

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;public class LoggingMiddleware
{private readonly RequestDelegate _next;private readonly ILogger<LoggingMiddleware> _logger;public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger){_next = next;_logger = logger;}public async Task InvokeAsync(HttpContext context){// 记录请求日志_logger.LogInformation($"Request logged: {context.Request.Path} at {DateTime.Now}");// 将请求传递给下一个中间件或处理程序await _next(context);}
}

然后,在 Startup.cs 文件的 Configure 方法中,注册这个中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILogger<Startup> logger)
{// 其他中间件// 注册日志中间件app.UseMiddleware<LoggingMiddleware>();// 其他中间件// 配置异常处理中间件等
}

在这个示例中,LoggingMiddleware 类接受 RequestDelegateILogger 作为构造函数参数,分别表示请求处理管道的下一个组件和日志记录器。在 InvokeAsync 方法中,记录请求的路径和时间戳,然后调用 _next(context) 将请求传递给下一个中间件或处理程序。

这个中间件可以用于记录每个请求的基本信息,对于调试和监视应用程序的运行非常有用。

五、总结

ASP.NET Core 中间件是请求处理管道中的可插拔组件,通过自定义中间件,开发人员能够灵活处理请求和响应。创建自定义中间件的基本步骤包括编写类、注册和配置中间件,同时理解中间件的参数和上下文对象的使用。自定义中间件的需求源自对特定业务逻辑、性能优化和模块化的需求。

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

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

相关文章

leetcode 动态规划(单词拆分)

139.单词拆分 力扣题目链接(opens new window) 给定一个非空字符串 s 和一个包含非空单词的列表 wordDict&#xff0c;判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。 说明&#xff1a; 拆分时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。 …

图解智慧:数据可视化如何助你高效洞悉信息?

在信息爆炸的时代&#xff0c;数据扮演着越来越重要的角色&#xff0c;而数据可视化则成为解读和理解海量数据的得力工具。那么&#xff0c;数据可视化是如何帮助我们高效了解数据的呢&#xff1f;下面我就以可视化从业者的角度来简单聊聊这个话题。 无需深奥的专业知识&#x…

第1章 数据结构与算法介绍

文章目录 1.1 数据结构和算法内容介绍1.1.1 先看几个经典的算法面试题1.1.2 数据结构和算法的重要性1.1.3 本套数据结构和算法内容介绍1.1.4 课程亮点和授课方式 1.1 数据结构和算法内容介绍 1.1.1 先看几个经典的算法面试题  字符串匹配问题&#xff1a;&#xff1a; 有一…

wpf使用Popup封装数据筛选框

(关注博主后,在“粉丝专栏”,可免费阅读此文) 类似于DevExpress控件的功能 这是DevExpress的winform筛选样式,如下: 这是DevExpress的wpf筛选样式,如下: 这是Excel的筛选样式,如下: 先看效果 本案例使用wpf原生控件封装,功能基本上都满足,只是颜色样式没有写…

Kotlin中的委托

在Kotlin中&#xff0c;委托是一种强大的设计模式&#xff0c;它允许一个类将其一些职责委托给另一个类。这种机制通过关键字by来实现。委托有助于代码的重用&#xff0c;降低耦合性&#xff0c;并提供更清晰的类设计。在Kotlin中&#xff0c;有两种主要类型的委托&#xff1a;…

为何我选择山海鲸可视化:五大优势解析

在众多的可视化产品中&#xff0c;我选择了山海鲸可视化&#xff0c;这并非偶然。在对比了其他同类产品后&#xff0c;我发现山海鲸可视化具有许多独特的优势和特点&#xff0c;使得它成为了我心目中的理想选择。下面我简单说一下我选择这款产品的几大原因&#xff0c;希望对在…

最新国内可用GPT4、Midjourney绘画、DALL-E3文生图模型教程

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;文档对话总结DALL-E3文生图&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和…

【python 的各种模块】(9) 在python使用PIL( 即pillow模块 ) 修改图片

目录 1 导入PIL模块&#xff08;pillow&#xff09; 1.1 PIL的全称&#xff1a;Python Imaging Library 1.2 导入PIL模块 1.2.1 可用的导入形式 1.2.2 常用的导入形式 1.2.3 PIL下面的常用子模块 2 PIL.Image的方法 (读入&#xff0c;生成和显示图片) 2.1 用 PIL.Image…

蓝桥杯AcWing学习笔记 8-2数论的学习(下)

蓝桥杯 我的AcWing 题目及图片来自蓝桥杯C AB组辅导课 数论&#xff08;下&#xff09; 蓝桥杯省赛中考的数论不是很多&#xff0c;这里讲几个蓝桥杯常考的知识点。 约数个数定理 我们如何去求一个数的约数个数呢&#xff1f; N N N分解质因数的结果&#xff1a; N P 1 α…

HTML+CSS-02

阿里巴巴矢量图标库的使用 阿里巴巴网址矢量图标库网址 https://www.iconfont.cn/ 如何使用 选择需要的icon图标加入购物车下载代码 在将解压后的文件夹复制到项目中进入demo_index.html中打开就可以看到示例的三种用法 三种引入方法 Unicode 引用 Unicode 是字体在网页端…

vscode(visual studio code) 免密登陆服务器

1.生成密钥 首先&#xff0c;在本地&#xff0c;打开命令输入框&#xff1a; WinR–>弹出输入框&#xff0c;输入cmd,打开命令框。 然后&#xff0c;在命令框&#xff0c;输入 ssh-keygen -t rsa -C "love"按两次回车键&#xff0c;问你是否重写&#xff0c;选择…

人工智能SCI二区期刊Applied Intelligence高被引录用论文合集,含2024最新

今天给着急发论文的同学推荐一本期刊&#xff1a;《APPLIED INTELLIGENCE》。 该刊由SPRINGER出版商于1991年创刊&#xff0c;刊期Bimonthly&#xff0c;专注于人工智能和神经网络的研究&#xff0c;重点关注有关创新智能系统的方法论及其在解决现实生活复杂问题的研究进展&am…

Springboot中使用Filter过滤器

1、概述 springboot工程中使用Filter过滤器与其他地方使用基本相同&#xff0c;只是注入的方式不同。 2、创建Filter过滤器 实现Filter接口&#xff0c;重写doFilter方法 filterChain.doFilter(servletRequest,servletResponse);表示放行 public class MyFilter implement…

【AI】人工智能和天文大数据

目录 一、具体应用例子 1.1 星系分类 1.2 瞬态天体检测 1.3 光谱分析 1.4 引力波数据分析 二、关键技术详解 一、具体应用例子 1.1 星系分类 应用背景&#xff1a;随着天文望远镜技术的发展&#xff0c;积累了大量的星系图像。手动对这些图像进行分类几乎是不现实的&am…

Rocketmq rust版本-开篇

我是蚂蚁背大象(Apache EventMesh PMC&Committer)&#xff0c;文章对你有帮助给Rocketmq-rust star,关注我GitHub:mxsm&#xff0c;文章有不正确的地方请您斧正,创建ISSUE提交PR~谢谢! Emal:mxsmapache.com Rust重构Rocketmq,大家好我是mxsm(Apache EventMesh PMC&Comm…

隐私计算的技术体系有哪些

随着各行各业的数字化转型发展,围绕数据的数字化应用如雨后春笋般出现,数据作为业务过程的重要产品,数据作为一种资源、生产要素或商品,越来越得到大家的重视,同时,数据只有在交易流通中才能体现出价值,但需要数据安全的支撑。数据作为数字经济的生产要素之一,具有四方…

Leetcode 474 一和零

题意理解&#xff1a; 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 将字符串0和1的个数看作是该字符…

基于SSM的网上订餐管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

Python系列(2)—— 数据类型

Python核心数据类型 一、Numbers&#xff08;数字&#xff09;三、String&#xff08;字符串&#xff09;三、Tuple&#xff08;元组&#xff09;四、List&#xff08;列表&#xff09;五、Set&#xff08;集合&#xff09;六、Dictionary&#xff08;字典&#xff09; 在Pytho…

Go语言中的Pool

简介 Go语言中的pool是一个资源池&#xff0c;它可以存储一定数量的资源&#xff0c;这些资源可以被多个goroutine共享。Pool可以提高资源的利用率&#xff0c;减少资源的创建和销毁带来的开销。 原理 Pool的实现原理很简单&#xff0c;它使用一个队列来存储资源。当一个gor…