1. 概述
ASP.NET Core中的中间件是嵌入到应用管道中用于处理请求和响应的一段代码。
2. 使用 IApplicationBuilder 创建中间件管道
2.1 匿名函数
使用Run, Map, Use ,MapWhen等扩展方法来实现。
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; public class Startup { public void Configure(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("Hello World!"); }); } }
第一个Run委托终止了管道。
用 Use 将多个请求委托链接在一起。 next 参数表示管道中的下一个委托。 可通过不 调用 next 参数使管道短路。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.Use(async (context, next) => { context.Response.ContentType = "text/plain;charset=utf-8"; await context.Response.WriteAsync("进入第一个委托 执行下一个委托之前 "); // 调用管道中的下一个委托 await next.Invoke(); await context.Response.WriteAsync("结束第一个委托 执行下一个委托之后 "); }); app.Run(async context => { await context.Response.WriteAsync("进入第二个委托 "); await context.Response.WriteAsync("Hello World! "); await context.Response.WriteAsync("结束第二个委托 "); }); }
2.2 自定义中间件类
新建中间件类:MyMiddleware.cs
using Microsoft.AspNetCore.Http; public class MyMiddleware { private readonly RequestDelegate _next; // 在应用程序的生命周期中,中间件的构造函数只会被调用一次 public MyMiddleware(RequestDelegate next) { this._next = next; } public async Task InvokeAsync(HttpContext context) { await context.Response.WriteAsync("Hello World!"); await _next(context); } }
将自定义中间件配置到请求处理管道中,Startup.cs文件调整:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMiddleware<MyMiddleware>(); }
将中间件MyMiddleware改成扩展方法:
新建扩展类MyMiddlewareExtension.cs
using Microsoft.AspNetCore.Builder; public static class MyMiddlewareExtension { public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder) { // 使用UseMiddleware将自定义中间件添加到请求处理管道中 return builder.UseMiddleware<MyMiddleware>(); } }
将自定义中间件配置到请求处理管道中,Startup.cs文件调整:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMyMiddleware(); }
2.3 自定义中间件类传入初始参数
public class GreetingOption { public string At { get; set; } public string To { get; set; } }
using Microsoft.AspNetCore.Http; public class GreetingMiddleware { private readonly RequestDelegate _next; private readonly GreetingOption _option; public GreetingMiddleware(RequestDelegate next, GreetingOption option) { _next = next; _option = option; } public async Task Invoke(HttpContext context) { var message = $"Good {_option.At} {_option.To}"; await context.Response.WriteAsync(message); } }
using Microsoft.AspNetCore.Builder; public static class GreetingMiddlewareExtension { public static IApplicationBuilder UseGreetingMiddleware(this IApplicationBuilder app, GreetingOption option) { return app.UseMiddleware<GreetingMiddleware>(option); } }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseGreetingMiddleware(new GreetingOption { At = "Morning", To = "Libing" }); }
3. IMiddleware
IMiddleware提供了强类型约束的中间件,其默认实现是MiddlewareFactory,接口定义如下:
public interface IMiddleware { Task InvokeAsync(HttpContext context, RequestDelegate next); }
IMiddlewareFactory用于创建IMiddleware实例及对实例进行回收,接口定义:
public interface IMiddlewareFactory { public IMiddleware Create (Type middlewareType); public void Release (IMiddleware middleware); }
3.1 自定义IMiddleware类型中间件
修改MyMiddleware,实现IMiddleware接口:
using Microsoft.AspNetCore.Http; public class MyMiddleware : IMiddleware { public async Task InvokeAsync(HttpContext context, RequestDelegate next) { await context.Response.WriteAsync("Hello World!"); await next(context); } }
将自定义中间件配置到请求处理管道中,Startup.cs文件调整:
public void ConfigureServices(IServiceCollection services) { // 在服务容器中注册自定义中间件 services.AddSingleton<MyMiddleware>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 使用 UseMiddleware() 把自定义中间件添加到管道中 app.UseMyMiddleware(); }