我是一个不爱说话的人,可是遇见你我变成了话痨。 --zhu
中间件(Middleware)
中间件概念:
中间件是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请求和响应按照中间件组装的顺序在中间件之间流转的过程。开发人员可以对组成管道的中间件按照需要进行自由组合。
中间件和Filter区别:
中间件是ASP.NET Core这个提供的功能,而Filter是ASP.NET Core MVC中提供的功能。ASP.NET Core MVC是MVC中间件提供的框架,而Filter属于MVC中间件提供的功能。
1、中间件可以处理所有的请求,而Filter只能处理对控制器的请求;中间件运行在一个更底层、更抽象的级别,因此在中间件中无法处理MVC中间件特有的概念。
2、中间件和Filter可以完成很多相似功能。“未处理异常中间件”和“为处理异常Filter”,“请求限流中间件”和“请求限流Filter”的区别。
3、优先选择使用中间件;但是如果这个组件只针对MVC或者需要调用一些MVC相关的类的时候,我们只能选择Filter。
中间件的三个概念
Map、Use和Run。Map用来定义一个管道可以处理哪些请求,Use和Run用来定义管道,一个管道由多个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。
简单自定义中间件
为了能够更清晰地了解中间件,我们创建一个空的ASP.NET Core项目,然后手动添加中间件。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.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)=>{
context.Response.ContentType="text/html";
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("hello middleware </br>");
});
});
app.Run();
简单自定义中间件类
1、如果中间件的代码比较复杂,或者我们需要重复使用一个中间件的话,我们最好把中间件的代码放到一个单独的“中间件类”中。
2、中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。这个类还需要定义一个名字为Invoke或者InvokeAsync方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和Invoke(或者InvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。
3、示例:检查请求中是否有password=123的查询字符串,而且会把请求报文体按照Json格式尝试解析为dynamic对象放入context.Items中供后续的中间件或者Run使用。
public class CheckAndParsingMiddleware
{
private readonly RequestDelegate next;
public CheckAndParsingMiddleware(RequestDelegate next)
{
this.next=next;
}
public async Task InvokeAsync(HttpContext context)
{
string pwd=context.Request.Query["password"];
if(pwd=="123")
{
if(context.Request.HasJsonContentType())
{
var reqStream=context.Request.BodyReaderAsStream();
dynamic? jsonObj=DJson.Parse(reqStream);
context.Items["BodyJson"]=jsonObj;
}
await next(context);
}
else context.Request.StatusCode=401;
}
}
标签:Core,await,中间件,next,context,NET
From: https://www.cnblogs.com/zhusichen/p/18329887