网上有很多介绍中间件的解释,我个人的理解时,在应用程序运行的时候,一个请求进来开始,到结束出来,中间进行处理的方法就是中间件,中间件可以有很多个,依次会进行处理,比如我想在请求返回时加点什么东西,比如我想中途打印个日志什么的,再请求应答回去之间,都是再各个中间件内进行处理,当然中间件里面怎么处理就是开发者自己的程序,ASP.NET Core只是提供了一个个中间件的入口模板。
中间件里面包含了微软封装好的可以直接调用的中间件,也有自定义的中间件,下面时中间件的一些内容
- 可同时被访问和请求
- 可以处理请求后,然后将请求传递给下一个中间件
- 可以处理请求后,并使管道短路
- 可以处理传出响应
- 中间件时按照添加的顺序执行的
下面开始展示一些中间件的细节
1、项目开头的中间件
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();//里面的build是运行编译生成文件交予环境去托管,run()运行以后接受客户端发过来的请求和接受
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>//默认配置的建立
{
webBuilder.UseStartup<Startup>();//此处的.UseStartup就是一个中间件,用于加载Startup这个类
});
}
2、项目中的中间件,在startup里面
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
......
app.UseRouting();//微软自己封装的中间件,还有好多,比如初始页面,日志什么的,很多
app.Use(async (content, next) =>
{
await content.Response.WriteAsync("requst in 1");
await next();
await content.Response.WriteAsync("requst out 1");
});
app.Use(async (content, next) =>
{
await content.Response.WriteAsync("requst in 2");
await next();
await content.Response.WriteAsync("requst out 2");
});
app.Run(async (content) =>
{
await content.Response.WriteAsync("hello world");
});
}
可以看见打印出来的结果是
如图下所示,可以解释一下,主要是use和run中间件,其他的中间件很多都是可以自定义或者微软封装的中间件,大同小异,use中间件有很多个,run只能有一个,可以把run当成以后的中间件,后续跟的中间件就会被抛弃掉,use中间件的顺序很想递归的感觉,就是,请求进来以后,先执行next()方法前面的程序,然后执行next()方法,这个方法会跳转到下一个中间件执行,直到最后一个中间件,随后倒数第二个中间件next()方法之后的程序执行,再倒数第三个,倒数第四个依次执行
3、使用 IStartupFilter 注册中间件
编写RequestSetOptionsMiddleware 中间件
public class RequestSetOptionsMiddleware
{
private readonly RequestDelegate _next;
public RequestSetOptionsMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
await _next(httpContext);
await httpContext.Response.WriteAsync("add RequestSetOptionsMiddleware content");
}
}
在 RequestSetOptionsStartupFilter 类中配置 RequestSetOptionsMiddleware:
namespace WebStartup.Middleware;
// <snippet1>
public class RequestSetOptionsStartupFilter : IStartupFilter
{
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
builder.UseMiddleware<RequestSetOptionsMiddleware>();
next(builder);
};
}
}
// </snippet1>
IStartupFilter 在startup中注册:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IStartupFilter, RequestSetOptionsStartupFilter>();
}
结果输出