一、什么是中间件
ASP.NET Core为你准备了一条产线(HTTP request pipeline)、多道工序(Middleware),最终的产出(Http Response)由经过工序多少及顺序决定。
1、服装生产线
^_^ 男士衬衣 = │裁剪│→│印个篮球│→│缝制│→│整烫│→│检验│→│包装│
^_^ 半成品男士衬衣 = │裁剪│→│印个篮球│→│结束│ │缝制│→│整烫│→│检验│→│包装│
^_^ 女士衬衣 = │裁剪│→│印个城堡│→│印个萝莉│→│缝制│→│整烫│→│检验│→│包装│
^_^ 围裙= │裁剪│→│缝制│→│包装│
(1)从生产衣服可得出
默认工序 —— 裁剪、缝制、整烫、检验、包装
自定义工序 —— 印个篮球、印个城堡、印个萝莉
产品 —— 男士衬衣、半成品男士衬衣、女士衬衣、围裙
(2)结论
产品 = 组合工序(“默认工序”+“自定义工序”)
(3)注意
A、一般情况下是不会去打乱“默认工序”的顺序(如 剪裁→包装 改为 包装→剪裁),不然可能就四不像了(异常);
B、“中间件”处理完后可以直接结束(叫 断路/短路),不再往下传递(如 半成品男士衬衣)
2、官方
- ASP.NET Core 请求管道包含一系列请求委托(中间件),依次调用

- 典型应用中的中间件顺序

二、示例
1、一切从Configure开始
(1)Startup里
public class Startup { // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //认证中间件 app.UseAuthentication();
(2)在主机构建器里
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureServices(services => { services.AddControllersWithViews(); }) .Configure(app => { //认证中间件 app.UseAuthentication();
2、自定义“错误处理中间件”
问题:中间件的写法是怎样?要分几个类?怎样让代码看上去更优雅?
思路:请参考“内置的中间件”!ASP.NET Core是开源的!ASP.NET Core是开源的!ASP.NET Core是开源的!
(1)错误处理
/// <summary>
/// 错误处理中间件
/// </summary>
public class ErrorHandleMiddleware
{
private readonly RequestDelegate _next;
/// <summary>
/// 初始化实例
/// </summary>
/// <param name="next">下一个中间件管道.</param>
public ErrorHandleMiddleware(RequestDelegate next)
{
_next = next ?? throw new ArgumentNullException(nameof(next));
}
/// <summary>
/// 执行中间件
/// </summary>
/// <param name="context">The <see cref="HttpContext"/>.</param>
public async Task Invoke(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
try
{
await _next(context);
}
catch (Exception ex)
{
//异常处理
await ResultOperate.DirectFail(context, context.Response.StatusCode, ex.Message);
}
finally
{
//根据状态码处理
var statusCode = context.Response.StatusCode;
var msg = "";
switch (statusCode)
{
(2)中间件的扩展方法
/// <summary>
/// 添加中间件的扩展方法
/// </summary>
public static class ErrorHandleExtensions
{
public static IApplicationBuilder UseErrorHandle(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<ErrorHandleMiddleware>();
}
}
(3)使用它 - 成为一个名副其实的中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}
app.UseHttpsRedirection();
app.UseRouting();
//认证中间件
app.UseAuthentication();
//错误处理中间件(需要放在“授权中间件”前,不然遇到401就直接断路OVER了)
app.UseErrorHandle();
//授权中间件
app.UseAuthorization();
三、参考
-
ASP.NET Core 中间件
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1
-
ASP.NET Core 中的应用启动
https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/startup?view=aspnetcore-3.1
-
UseAuthorization授权中间件 - 源码
https://github.com/dotnet/aspnetcore/tree/master/src/Security/Authorization/Policy/src
