.NET Core开发实战课程备忘(13) -- 中间件:掌握请求处理过程的关键
核心对象
IApplicationBuilder
:让我们注册我们自己的中间件
RequestDelegate
:我们处理整个请求的委托
代码实现 创建项目 创建名字为MiddlewareDemo
的ASP.NET Core
项目,类型为API
直接注入委托 Startup.Configure
方法里,在app.UseHttpsRedirection()
中间件之前添加以下代码:
1 2 3 4 5 app.Use(async (context, next) => { await next(); await context.Response.WriteAsync("Hello world -- my middleware in delegate" ); });
运行代码访问/WeatherForecast
,可以看到原本的json后面会添加Hello world -- my middleware in delegate
这句话
对特定路径注册特定中间件 注释掉上面的代码,在原处新增以下代码
1 2 3 4 5 6 7 8 app.Map("/abc" , builder => { builder.Use(async (context, next) => { await next(); await context.Response.WriteAsync("Hello world abc -- from map middleware" ); }); });
运行代码访问/WeatherForecast
,结果与初始项目运行一致,访问/abc
,页面会返回Hello world abc -- from map middleware
对特定路径注册中间件升级版 当这个特定路径的判断比较复杂,可以使用MapWhen
来注册,注释掉上一步代码,在原处新增以下代码:
1 2 3 4 5 6 7 8 app.MapWhen(context => { return context.Request.Query.Keys.Contains("abc" ); }, builder => { builder.Use(async (context, next) => { await next(); await context.Response.WriteAsync("Hello world query abc -- from mapWhen middleware" ); }); });
这里表示当url参数里包含abc
这个函数,则触发指定的中间件,运行代码,运行代码访问/WeatherForecast
,结果与初始项目运行一致,访问/WeatherForecast?abc=aaa
,会在原有的返回结果后面添加Hello world query abc -- from mapWhen middleware
使用扩展方法来注册中间件(最佳姿势) 自定义中间件是按约定来调用的,即中间件里需要包含一个InvokeAsync
方法,方法参数为HttpContext
,通常中间件不直接对外暴露,所以类的访问修饰符通常是默认的internal
,然后通过IApplicationBuilder
的扩展方法向外暴露
在根目录创建文件夹Middlewares/MyMiddleware
,在目录下创建两个文件MyMiddleware.cs
和MyMiddlewareExtension.cs
,具体代码如下:
MyMiddleware.cs
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using Microsoft.AspNetCore.Http;using Microsoft.Extensions.Logging;namespace MiddlewareDemo.Middlewares.MyMiddleware { class MyMiddleware { private readonly RequestDelegate _next; private readonly ILogger<MyMiddleware> _logger; public MyMiddleware (RequestDelegate next,ILogger<MyMiddleware> logger ) { _next = next; _logger = logger; } public async Task InvokeAsync (HttpContext context ) { using (_logger.BeginScope("TraceIdentifier:{TraceIdentifier}" ,context.TraceIdentifier)) { _logger.LogDebug("开始执行MyMiddleware中间件" ); await _next(context); _logger.LogDebug("执行MyMiddleware中间件结束" ); } } } }
MyMiddlewareExtension.cs
代码:
1 2 3 4 5 6 7 8 9 10 11 12 using Microsoft.AspNetCore.Builder;namespace MiddlewareDemo.Middlewares.MyMiddleware { public static class MyMiddlewareExtension { public static IApplicationBuilder UseMyMiddleware (this IApplicationBuilder app ) { return app.UseMiddleware<MyMiddleware>(); } } }
因为这里使用了日志作用域,所以还需要到appsettings.json
里修改以下日志配置,具体内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "Logging" : { "LogLevel" : { "Default" : "Trace" , "Microsoft" : "Warning" , "Microsoft.Hosting.Lifetime" : "Information" }, "Console" : { "IncludeScopes" : true , "LogLevel" : { "MiddlewareDemo.Middlewares.MyMiddleware.MyMiddleware" : "Trace" } } }, "AllowedHosts" : "*" }
回到Startup.Configure
,注释掉前面的测试代码,在原处新增以下代码:
运行项目,访问/WeatherForecast
,可以看到控制台打印出了对应的日志