P7-6 中间件
中间件
什么是中间件
中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。
- 1、广义上来讲:Tomcat、WebLogic、Redis、IIS等都可以称作中间件;
- 狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。
- 2、中间件由前逻辑、next、后逻辑3部分组成,
- 前逻辑为第一段要执行的逻辑代码、
- next为指向下一个中间件的调用、
- 后逻辑为从下一个中间件执行返回所执行的逻辑代码。
- 每个HTTP请求都要经历一系列中间件的处理,每个中间件对于请求进行特定的处理后,再转到下一个中间件,最终的业务逻辑代码执行完成后,响应的内容也会按照处理的相反顺序进行处理,然后形成HTTP响应报文返回给客户端。
- 3、中间件组成一个管道,整个ASP.NET Core的执行过程就是HTTP请求和响应按照中间件组装的顺序在中间件之间流转的过程。
- 在.net framework中大部分的中间件都是固定的,不能自由组合
- 但到了ASP.NET Core时代,开发人员可以对组成管道的中间件按照需要进行自由组合。
中间件的3个概念
- 3个重要的概念:Map、Use和Run。
- Map用来定义一个管道可以处理哪些请求
- Map就是服务员,引导你去哪个最适合的桌子上吃饭
- Use和Run用来定义管道,一个管道由若干个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。
- Use就是需要吃的菜。Run就是付钱
- Map用来定义一个管道可以处理哪些请求
简单演示中间件
- 为了能够更清晰地了解中间件,我们创建一个空的ASP.NET Core项目,然后手动添加中间件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22app.Map("/test", async appbuilder =>
{
appbuilder.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>");
});
appbuilder.Use(async (context, next) =>
{
await context.Response.WriteAsync("2 Start<br>");
await next.Invoke();
await context.Response.WriteAsync("2 End<br>");
});
appbuilder.Run(async ctx =>
{
await ctx.Response.WriteAsync("Run<br>");
});
});
简单的自定义中间件
- 1、如果中间件的代码比较复杂,或者我们需要重复使用一个中间件的话,我们最好把中间件的代码放到一个单独的“中间件类”中。
- 2、中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。这个类还需要定义一个名字为Invoke或InvokeAsync的方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和Invoke(或InvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。
小练习
需求:检查请求中是否有password=123的查询字符串,而且会把请求报文体按照Json格式尝试解析为dynamic类型的对象(Nuget:Install-Package Dynamic.Json),并且把dynamic对象放入context.Items中供后续的中间件或者Run使用。
案例:自己动手模仿Web API 框架
- 分析杨中科老师写的简练板的Web API框架
- 作为了解即可,一般项目中,我们直接使用内置的组件即可
分析
- 一共有3个中间件
- MyStaticFilesMiddleware(静态网站加载的中间件)
- 用来处理对wwwroot文件夹下的静态文件的访问
- MyWebAPIMiddleware(方法请求中间件)
- 用来处理对控制器类的访问,没有就执行下一个中间件
- NotFoundMiddleware(404中间件)
- 向客户端写入状态码404的响应
- MyStaticFilesMiddleware(静态网站加载的中间件)
- 中间件的组装顺序非常重要
- 这个框架是先加载静态网站(因为静态快)
- 然后加载方法请求
- 如果上面两张都没有成功,就运行404
- 这个框架是先加载静态网站(因为静态快)
- 比如NotFoundMiddleware一定要放到最后,如果把NotFoundMiddleware放到其他中间件的前面,它就会使请求短路
案例:Markdown转换器 中间件
需求
- 1、Markdown格式不被浏览器支持;所以,编写一个在服务器端把Markdown转换为HTML的中间件。
- 2、我们开发的中间件是构建在ASP.NET Core内置的StaticFiles中间件之上,并且在它之前运行,所有的*.md文件都被放到wwwroot文件夹下,当我们请求wwwroot下其他的静态文件的时候,StaticFiles中间件会把它们返回给浏览器,而当我们请求wwwroot下的*.md文件的时候,我们编写的中间件会读取对应的*.md文件并且把它们转换为HTML格式返回给浏览器。
实现
- 需要用到两个插件
- Ude.NetStandard:文本编码检测
- MarkdownSharp:Markdown格式转化成HTML文件
筛选器与中间件的区别
关系
- 中间件是ASP.NET Core这个基础提供的功能
- 而Filter是ASP.NET Core MVC中提供的功能。
- ASP.NET Core MVC是由MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。
- ASP.NET Core MVC是由MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。
区别
1、从上图中可以看出来,中间件和筛选器所处的层级是不同的
- 中间件是一个基础的概念
- 筛选器是MVC中间件中的机制而已
2、处理请求
中间件可以处理所有的请求,无论是针对控制器的请求还是静态文件等的请求
- 但中间件运行在一个更底层、更抽象的级别,因此在中间件中无法处理MVC中间件特有的概念。
筛选器只能处理对控制器的请求
3、功能
- 中间件和Filter可以完成很多相似的功能。
- 由于中间件工作在比筛选器更低的层级中,因此在实现同样的功能的时候,中间件的运行效率更高
- 比如“未处理异常中间件”和“未处理异常Filter”;“请求限流中间件”和“请求限流Filter”的区别。
- 中间件和Filter可以完成很多相似的功能。
4、选择
- 优先选择使用中间件;
- 但是如果这个组件只针对MVC或者需要调用一些MVC相关的类的时候,我们就只能选择Filter。
P7-6 中间件
http://example.com/2024/10/12/Net Core2022教程/第7章:ASP.NET Core 基础组件/P7-6 中间件/