您现在的位置是:首页 >技术杂谈 >.Net中间件的概念---杨中科笔记网站首页技术杂谈
.Net中间件的概念---杨中科笔记
什么是中间件?
中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。
中间件组成一个管道,整个ASP.NET Core的执行过程就是HTTP请求和响应按照中间件组装的顺序在中间件之间流转的过程。开发人员可以对组成管道的中间件按照需要进行自由组合。
中间件的三个概念
Map、Use和Run。Map用来定义一个管道可以处理哪些请求,Use和Run用来定义管道,一个管道由若干个Use和一个Run组成,每个Use引入一个中间件,而Run是用来执行最终的核心应用逻辑。
使用场景
自定义中间件的使用场景是当你需要在应用程序的请求和响应处理中添加一些特定的逻辑或功能时,例如身份验证、错误处理、日志记录、缓存等。. ASP.NET Core 提供了一些内置的中间件组件,但你也可以编写自己的中间件来满足你的需求。
常见的 .Net 中间件的案例有:
- 身份验证中间件:验证用户的身份,并在上下文中设置用户主体。
- 静态文件中间件:提供静态文件,如图片、CSS、JavaScript 等。
- 路由中间件:将请求映射到终结点,如控制器、页面、信号 R 中心等。
- 异常处理中间件:捕获未处理的异常,并返回友好的错误页面或响应。
- 日志记录中间件:记录请求和响应的详细信息,以便进行调试或分析。
中间件与过滤器的区别
中间件和过滤器都是用来在请求和响应的过程中添加一些逻辑或功能的组件,但它们有一些区别。 中间件是在应用程序管道中的一个组件,它可以拦截请求并决定是否将请求转移给下一个中间件,或者直接返回响应。过滤器是在 MVC 框架中的一个组件,它可以在控制器的动作执行前后添加一些逻辑或功能,例如授权、异常处理、缓存等。过滤器只能应用于 MVC 的请求,而中间件可以应用于任何类型的请求。
优先选择使用中间件;但是如果这个组件只针对MVC或者需要调用一些MVC相关的类的时候,我们就只能选择Filter。
简单定义一个中间件
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) => { 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(); |
使用中间件类:
中间件类是一个普通的.NET类,它不需要继承任何父类或者实现任何接口,但是这个类需要有一个构造方法,构造方法至少要有一个RequestDelegate类型的参数,这个参数用来指向下一个中间件。这个类还需要定义一个名字为Invoke或InvokeAsync的方法,方法至少有一个HttpContext类型的参数,方法的返回值必须是Task类型。中间件类的构造方法和Invoke(或InvokeAsync)方法还可以定义其他参数,其他参数的值会通过依赖注入自动赋值。
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())//判断请求是否是Json类型 { var reqStream = context.Request.BodyReader.AsStream(); dynamic? jsonObj = DJson.Parse(reqStream); context.Items["BodyJson"] = jsonObj; } await next(context); } else context.Response.StatusCode = 401; } } |
配置文件配置
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Map("/test", async appbuilder => { appbuilder.UseMiddleware<CheckAndParsingMiddleware>(); appbuilder.Run(async ctx => { ctx.Response.ContentType = "text/html"; ctx.Response.StatusCode = 200; dynamic? jsonObj = ctx.Items["BodyJson"]; int i = jsonObj.i; int j = jsonObj.j; await ctx.Response.WriteAsync($"{i}+{j}={i+j}"); }); }); app.Run(); |