WebAPI-中间件
WebAPI-中间件
ASP.NETCore中,filter的概念更像是一个面向AOP编程的增强类
而ASP.NETCore中间件的概念,更像是JavaWeb的Filter或者是SpringMVC中的拦截器一样
需要注意的是,Java中也有中间件的概念,不过更多指的是Tomcat或Redis这一类的应用服务
大部分时间,我们极少需要自己定义中间件,一般都使用框架定义好的中间件,所以对框架提供的中间件要熟悉,另外要熟悉HttpContext对象的常用成员
Map管道
在启动类中,我们可以见到很多app.Use方法来定义的中间件
在这里,我们可以使用Map来自定义管道
,实现不同的http请求路径而使用不同的中间件
定义在Map管道之外的中间件,则应用于所有请求
除了Map方法之外,还有MapGet、MapPost、MapWhen等指定管道的方法,但实际项目中,如果不是开发框架,比较少用到Map
中间件的注册顺序很重要
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 指定处理“/test”路径请求的管道
app.Map("/test", async testBuilder =>
{
// 第一个中间件
testBuilder.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/>");
});
// 第二个中间件
testBuilder.Use(async (context, next) =>
{
await context.Response.WriteAsync("2 Start<br/>");
await next.Invoke();
await context.Response.WriteAsync("2 End<br/>");
});
//Run终点
testBuilder.Run(async ctx => { await ctx.Response.WriteAsync("hello,it is run<br/>"); });
});
app.Run();
}
}
Context
每一次HTTP请求,框架会自动生成一个HttpContext类型的对象,称之为上下文,可以记录了请求路径、请求参数、请求客户端、响应报文、响应流、用户、自定义Items等信息。在中间件的前后逻辑和控制器中,均可以对HttpContext对象进行读写操作
Next
在一个中间件中,有三部分组织,①前逻辑;②next方法;③后逻辑
HTTP请求到达服务器后,先由框架进行请求解析,然后进入第一个中间件,先执行前逻辑,然后由中间件自己决定是否执行next.Invoke(),如不执行,则请求中断,如执行,则请求进入下一个中间件
当Controller控制器方法执行之后,再逆向执行中间件进行响应处理
中间件类
同样的,我们可以自定义中间件类,将中间件代码放入其中
中间件类是一个很普通的类,他不需要继承任何父类方法或实现任何接口,但这个类需要有一个构造方法,构造方法至少有一个RequestDelegate类型的参数
这个类型的参数对象(next)用来放行中间件,让其到达下一个中间件
这个类需要定义一个名字为Invoke或InvokeAsync的方法,方法至少有一个HttpContext类型的参数(context),其方法的返回值必须是Task类型
注:无论是中间件类还是Invoke方法,都可以通过DI来注入其他对象
using Microsoft.AspNetCore.Http;
using System;
using System.Threading.Tasks;
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
public LoggingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// 请求前的日志记录
Console.WriteLine($"Request started: {context.Request.Method} {context.Request.Path}");
// 调用下一个中间件
await _next(context);
// 响应后的日志记录
Console.WriteLine($"Request completed with status code: {context.Response.StatusCode}");
}
}
注册中间件
需要注意的是,通过UseMiddleware<>方法注册自定义中间件,而不是Use方法
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 通过UseMiddleware方法注册自定义中间件
app.UseMiddleware<TestMiddleware>();
app.Run();
}
}
深度理解
ASP.NETCore框架内置很多中间件,通过这些内置的中间件,我们可以快速的构建一个WebAPI甚至是MVC的架构
对于Filter(筛选器)而言,他们有一些相同点和不同点:
- 中间件可以处理所有的请求,而Filter只能处理对控制器的请求
- 中间件运行在一个更底层、更抽象的级别
- 中间件和Filter可以完成很多相似的功能,例如:
- 未处理异常中间件和未处理异常Filter
- 请求限流中间件和请求限流Filter
- 优先选择使用中间件