ASP.NET Core Middleware

中间件(Middleware)是ASP.NET Core中的一个重要特性。所谓中间件就是嵌入到应用管道中用于处理请求和响应的一段代码。ASP.NET Core Middleware可以分为两种类型:

  • Conventional Middleware

  • IMiddleware

Conventional Middleware

这种中间件没有实现特定的接口或者继承特定类,它更像是Duck Typing (你走起路来像个鸭子, 叫起来像个鸭子, 那么你就是个鸭子)。有两种表现形式:

匿名方法

这种方式又称为内联中间件(in-line middleware),可以使用Run, Map, Use,MapWhen等扩展方法来实现。如:

640?wx_fmt=png

IApplicationBuilder的扩展方法:RunMapMapWhen
Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware),最终都会调用IApplicationBuilder接口中的Use(Func<RequestDelegate, RequestDelegate> middleware)方法来实现向请求处理管道中注入中间件,后面会对源码做分析。

自定义中间件类

这种形式利于代码的复用,如:

640?wx_fmt=png

将自定义中间件配置到请求处理管道中

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{app.UseXfhMiddleware();
}

IMiddleware

IMiddleware提供了强类型约束的中间件,其默认实现是MiddlewareFactory,接口定义如下:

public interface IMiddleware
{Task InvokeAsync(HttpContext context, RequestDelegate next);
}

IMiddlewareFactory用于创建IMiddleware实例及对实例进行回收,接口定义:

640?wx_fmt=png

将中间件注入到请求处理管道:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{app.UseMyMiddleware();
}

 

使用IMiddleware类型的中间件需要在容器中进行注册,否则抛异常,具体原因下面分析:

 

640?wx_fmt=png

 将中间件注入到容器中:

640?wx_fmt=png

一段警告

下面贴一段微软文档中的警告,大意是不要试图去改变已发往客户端的响应内容,否则可能会引发异常。实在是太懒了,不想翻译就把原文贴出来了:

Warning

Don't call next.Invoke after the response has been sent to the client. Changes to HttpResponse after the response has started throw an exception. For example, changes such as setting headers and a status code throw an exception. Writing to the response body after calling next:

  • May cause a protocol violation. For example, writing more than the stated Content-Length.

  • May corrupt the body format. For example, writing an HTML footer to a CSS file.

HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.


UseMiddleware

前面将自定义中间件注入到请求处理管道时用到了UseMiddleware方法,从方法签名中可以看到UserMiddleware可以接受多个参数:

640?wx_fmt=png

接下来我们看下UserMiddleware方法的具体实现,由于该方法代码量较大,所以这里只看其中的关键部分,方法整体流程如下:

640?wx_fmt=png

  • 该方法首先判断传入的middleware是否是IMiddleware类型,如果是则调用UseMiddlewareInterface

从这段代码中可以看到IMiddlewareFactory负责创建并回收IMiddleware对象

640?wx_fmt=png

MiddlewareFactoryCreate方法中可以看到,IMiddleware实例是从容器中获取的,若容器中找不到则会抛出异常:

640?wx_fmt=png

  • 若是Conventional Middleware则判断传入的middleware是否符合约束

首先判断传入的middleware中是否仅包含一个名称为Invoke或InvokeAsync的公共实例方法

640?wx_fmt=png

其次判断方法的返回类型是否是Task

640?wx_fmt=png

然后再判断,方法的第一个参数是否是HttpContext类型:

640?wx_fmt=png


对于InvokeInvokeAsync仅包含一个HttpContext类型参数的情况用到了反射(ActivatorUtilities.CreateInstance方法中)来构建RequestDelegate

640?wx_fmt=png

对于包含多个参数的情况,则使用了表达式树来构建RequestDelegate

640?wx_fmt=png

完整的代码可以在Github上看到。

Use(Func<RequestDelegate, RequestDelegate> middleware)

上述所有中间件,最终都会调用IApplicationBuilder接口中的Use(Func<RequestDelegate, RequestDelegate> middleware)方法来实现向请求处理管道中注册中间件,该方法在ApplicationBuilder类的实现如下:

640?wx_fmt=png

从上面代码中可以看到,中间件是一个RequestDelegate类型的委托,请求处理管道其实是一个委托列表,请求委托签名如下:

public delegate Task RequestDelegate(HttpContext context);

 


与ASP.NET处理管道的区别

 

 

640?wx_fmt=png

 

传统的ASP.NET的处理管道是基于事件模型的,处理管道有多个IHttpModule和一个IHttpHandler组成。请求处理管道中各个模块被调用的顺序取决于两方面:

  • 模块所注册事件被触发的先后顺序

  • 注册同一事件的不同模块执行先后顺序有Web.config中的配置顺序决定

 

640?wx_fmt=jpeg

 

 

ASP.NET Core的请求处理管道则是有一堆中间件组成,相对ASP.NET更简单。

中间件处理请求和响应的顺序只与其在代码中的注册顺序有关:处理请求按注册顺序依次执行,处理响应按注册顺序反方向依次执行。

其次,在ASP.NET Core中只需使用代码,而无需使用Global.asaxWeb.config来配置请求处理管道。

小结

所谓中间件就是嵌入到应用管道中用于处理请求和响应的一段代码,它主要有两个作用:

  • 处理请求和响应

  • 可以阻止请求发往请求处理管道中的下一个中间件

在ASP.NET Core中,中间件是以RequestDelegate委托的形式体现的。

ASP.NET Core中整个请求处理管道的创建是围绕这种IApplicationBuilder接口进行的,请求处理管道是一个List<RequestDelegate>类型的列表。

推荐阅读

ASP.NET Core Middleware
Factory-based middleware activation in ASP.NET Core
Migrate HTTP handlers and modules to ASP.NET Core middleware
ASP.NET MVC5请求处理管道和生命周期
用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识

原文地址:https://www.cnblogs.com/Cwj-XFH/p/9690728.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

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

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

相关文章

NOIP复健计划——动态规划

树形DP [POI2011] DYN-Dynamite 二分KKK check(mid)&#xff1a; 能否选出mmm个点&#xff0c;使得 ∀i为关键点&#xff0c;Minjisselected{dis(i,j)}≤mid\forall i为关键点&#xff0c;Min_{j\ is\ selected}\{dis(i,j)\}\leq mid∀i为关键点&#xff0c;Minj is selecte…

【每日一题】7月6日精讲—平衡二叉树

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 平衡二叉树&#xff0c;顾名思义就…

MATLAB灰色预测

一.灰色预测 1.灰色系统下的灰色预测 <1>什么是灰色系统&#xff1f; 所谓的灰色系统其实就是夹杂在白色系统和黑色系统之中的一种系统&#xff0c;而白色系统就是全部信息已知的系统&#xff0c;黑色系统就是全部信息未知的系统。所以&#xff0c;夹在这两种系统中间…

ASP.NET Core 中的依赖注入

什么是依赖注入软件设计原则中有一个依赖倒置原则&#xff08;DIP&#xff09;&#xff0c;为了更好的解耦&#xff0c;讲究要依赖于抽象&#xff0c;不要依赖于具体。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。什么是依…

【每日一题】7月7日题目精讲—最短路

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 给一个连通图&#xff0c;每次询问…

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…

邓公数据结构C++语言版学习笔记1

1. 对于计算幂2n2^n2n的算法优化 暴力算法时间复杂度O(n)O(n)O(n) __int64 power2BF_I(int n) //幂函数2^n算法&#xff08;蛮力迭代版&#xff09;&#xff0c;n > 0{ __int64 pow 1; //O(1)&#xff1a;累积器刜始化为2^0while (0 < n --) //O(n)&#xff1a;迭代n轮…

HttpClientFactory系列二:集成Polly处理瞬态故障

前言&#xff1a;最近&#xff0c;同事在工作中遇到了使用HttpClient,有些请求超时的问题&#xff0c;辅导员让我下去调研一下&#xff0c;HttpClinet的使用方式已经改成了之前博客中提到的方式&#xff0c;问题的原因我已经找到了&#xff0c;就是因为使用了伪异步&#xff0c…

邓公数据结构C++语言版学习笔记——二叉树

二叉树的遍历 一. preorder——先序遍历VLR 1. 递归先序遍历 2. 迭代先序遍历 3.先序遍历图解 二. inorder——先序遍历LVR 1. 递归中序遍历 2.迭代中序遍历 3.迭代中序遍历优化空间复杂度 <1>定义直接后继 <2>借用直接后继优化算法 解释&#xff1a;…

二分图匹配--匈牙利算法

文章目录二分图&#xff1a;匹配匈牙利算法代码&#xff1a;二分图&#xff1a; 二分图是一个无向图&#xff0c;点集分成子集X和Y&#xff0c;图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时&#xff08;包括0&#xff09;&#xff0c;G就是一个…

《Office 365开发入门指南》上市说明和读者服务

写在最开始的话拙作《Office 365开发入门指南》上周开始已经正式在各大书店、在线商城上市&#xff0c;欢迎对Office 365的开发、生态感兴趣的开发者、项目经理、产品经理参考本书&#xff0c;全面了解Office 365带来的全新机遇以及在具体业务应用开发中的场景。写作本书差不多…

简单理解手机快充

浅谈手机快充 背景 智能手机发展这么些年&#xff0c;屏幕显示越来越清晰&#xff0c;拍照像素越来越高&#xff0c;处理器性能越来越强&#xff0c;运行内存甚至开始超过PC&#xff0c;不过手机的续航还是一个问题&#xff1a;处理器性能以及一系列的增强无疑对电池是一个巨…

【送书活动】C# 程序员的自我修养

如果希望成为一个C# 高手&#xff0c;或者至少是合格的C# 程序员&#xff0c;应该懂些什么&#xff1f;《C#从现象到本质》&#xff08;以下简称本书&#xff09;试图回答这个问题。实际上&#xff0c;在本书问世之前&#xff0c;市面上已经有很多优秀的C# 书籍&#xff0c;例如…

张善友:自由之精神,中国之队长

张善友&#xff0c;毕业于兰州大学数学系&#xff0c;2006年开始连任微软最有价值专家&#xff08;MVP&#xff09;&#xff0c;一直在社区宣导.NET开源项目&#xff0c;从早期的Mono到.NET Core&#xff0c;在社区被尊称为张队长&#xff0c;在腾讯工作11年后&#xff0c;进行…

CF461D-Appleman and Complicated Task【并查集】

正题 题目链接:https://www.luogu.com.cn/problem/CF461D 题目大意 n∗nn*nn∗n的网格需要填上xxx或ooo&#xff0c;其中有kkk个格子已经固定&#xff0c;求有多少中填写方案使得每个格子的四周都有偶数个ooo。 解题思路 约束条件相当于一个格子周围的异或和都为000&#xff…

工科数学分析无穷级数总结

目录序言一.常数项级数概念1. 什么是常数项无穷级数&#xff1f;2. 级数的收敛性与和两个特别的级数级数的判别方法①常数项级数判别法②正项级数的审敛准则③变号级数的审敛准则④绝对收敛二.函数项级数概念1. 什么是函数项级数&#xff1f;2. 函数项级数处处收敛与和函数一致…

dump解析入门-用VS解析dump文件进行排障

突然有一天部署在服务器的一个应用挂掉了&#xff0c;没办法只能进入服务器打开【事件查看器】查看下&#xff0c;好不容易找到了打开后一脸懵逼事件查看器查到的内容根本对我们排障没有任何作用。在这个时候如果有对应的dump文件就能派上用场了&#xff0c;只要有dump文件就能…

.NET Core部署中你不了解的框架依赖与独立部署

作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9703460.htmlNET Core项目发布的时候你有没有注意到这两个选项呢&#xff1f;有没有纠结过框架依赖与独立部署到底有什么区别呢&#xff1f;如果有的话那么这篇文章可以参考下&#xff01;为什么…