一、程序启动会创建一个管道,所有的中间件都以一层套一层的方式这个管道中对请求和返回响应进行处理
//.NET CORE MVC 的启动文件 Program.cs 里面默认配置一些中间件
//通常情况下我们会设置一个中间件配置类 startUp.cs 来设置服务的依赖以及配置中间件
//改造后的 Program
namespace MiddelWare_Demo
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(w =>
{
w.UseStartup<Startup>();
});
}
}
//新建的 Startup 用于配置管道的依赖和中间件
namespace MiddelWare_Demo
{
public class Startup
{
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; set; }
//创建构造依赖注入
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
//服务依赖注入
public void ConfigureServices(IServiceCollection services)
{
services
//.AddMvc()
.AddControllersWithViews()
.AddControllersAsServices()
.AddViewComponentsAsServices();
}
//配置管道中间件
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
// Configure the HTTP request pipeline.
if (!env.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//app.UseAuthorization();
app.UseEndpoints(routes =>
{
routes.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
二、中间件的作用:
1、选择是否将请求传递给管道中的下一个中间件
每个中间件都有权决定是否将请求传递到下一个中间件, app.Next(); 也可以直接做出响应,在管道中短路(返回) 每个控制器中的方法都是中间件中的一个处理方式(app.UseRouting()路由终端中间件的处理响应)
2、在管道中的下一个中间件的前后执行工作
3、创建中间件
3.1、中间件的本质是 委托集合,请求正序进入,响应倒叙返回
IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("this is middelware 1 begin");
await next(); //不设置的话就相当于终端中间件 app.Run(),将短路
await context.Response.WriteAsync("this is middelware 1 end");
});
//终结点中间件的本质 app.Run()
app.Run(async (context) =>
{
await context.Response.WriteAsync("</br> this is end point begin");
await context.Response.WriteAsync("</br> this is end point end");
});
}
3.2 终结点中间件
//终端路由中间件,用于识别路由
app.UseRouting();
/*........
这中间可以配置需要匹配路由后做出的一些设置。如:跨域设置,认证设置,反爬虫设置等等
.........*/
//终结点中间件,用来配置路由和终结点的映射关系
//这个终结点对应控制器中的某个方法
//上面的路由识别 API 和 MVC 是通用的,但是终结点要根据框架配置
app.UseEndpoints(routes =>
{
routes.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
3.4 创建中间件扩展
-
按照约定创建
-
具有类型为 RequestDelegate 的参数的公共构造函数
-
名为 Invoke 或者 InvokeAsync 的公共方法(这个方法必须有个 HttpContext 参数,返回一个 RequestDelegate)
public class MyMiddleWare
{
private readonly RequestDelegate _next;
public MyMiddleWare(RequestDelegate next)
{
_next = next;
}
//这边参数支持方法注入
public async Task InvokeAsync(HttpContext httpContext)
{
await httpContext.Response.WriteAsync($"this is my middleware begin{httpContext.Request.Path}");
await _next(httpContext);
await httpContext.Response.WriteAsync("this is my middleware end");
}
}
-
写应用扩展方法,调用中间件
public static class MyMiddelWareEntend
{
public static IApplicationBuilder UseMyMiddleWare(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleWare>();
}
}
-
在 StartUp.cs 文件中调用
//配置管道中间件
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("this is middelware 1 begin");
await next(); //不设置的话就相当于终端中间件 app.Run(),将短路
await context.Response.WriteAsync("this is middelware 1 end");
});
app.UseMyMiddleWare();
app.Run(async (context) =>
{
await context.Response.WriteAsync("</br> this is end point begin");
await context.Response.WriteAsync("</br> this is end point end");
});
}
运行结果
源自 18310807769的个人空间_哔哩哔哩_bilibili 学习笔记