什么是中间件? 中间件是插入到应用程序请求处理管道中的组件,负责处理HTTP请求和响应。每个中间件可以决定是否将请求传递给下一个中间件,并且可以在调用下一个中间件之前或之后执行特定的操作。
选择是否将请求传递给下一个中间件。 可以在调用下一个中间件之前和之后执行工作。 请求委托(Request Delegates)用于构建请求管道,处理每个HTTP请求。这些委托可以通过Run、Map和Use扩展方法进行配置。请求委托可以以内联匿名方法的形式指定,也可以在可重用的类中定义。这些类和匿名方法共同构成了中间件或中间件组件。
中间件机制允许开发者通过简单的链式调用来处理复杂的请求流程,例如静态文件服务、身份验证、异常处理等。将HTTP模块迁移到中间件解释了ASP.NET Core与早期版本(如ASP.NET)之间请求处理管道的主要差异,并提供了更多示例。
使用 IApplicationBuilder 构建中间件管道 ASP.NET Core 的请求处理流程由一系列请求委托组成,如下图所示(执行流程遵循黑色箭头)。每个委托可以在调用下一个委托之前和之后执行操作,并可以选择不将请求传递给下一个委托,这种行为称为短路。短路有助于避免不必要的处理步骤,提高性能。例如,静态文件中间件可以在找到匹配的静态文件后立即返回结果,从而短路后续的中间件。
中间件管道执行流程 最简单的ASP.NET Core应用程序可能只有一个请求委托来处理所有请求。在这种情况下,针对每个HTTP请求都调用一个匿名方法。
第一个 「app.Run」 委托终止整个请求处理管道。
示例中间件管道 示例中间件管道 可以看出请求委托的执行顺序严格遵循上述流程图。 配置 HTTP 管道 你可以使用 Use、Run 和 Map 方法来配置HTTP管道。
Use 方法可以使管道短路,即不再调用后续的请求委托。 Run 方法通常用于定义管道的最终处理逻辑,一些中间件组件可能暴露 Run 方法以在管道末端运行。 Map 扩展方法用于根据请求路径分支请求流水线,如果请求路径以给定路径开头,则执行分支。 内置中间件 中间件 作用 Authentication 提供身份验证支持 CORS 配置跨域资源共享 Response Caching 提供缓存响应支持 Response Compression 提供响应压缩支持 Routing 定义和约束请求路由 Session 提供用户会话管理 Static Files 为静态文件和目录浏览提供服务支持 URL Rewriting Middleware 用于重写 URL 并将请求重定向
自定义中间件 public class RequestCultureMiddleware { private readonly RequestDelegate _next; public RequestCultureMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext context) { var cultureQuery = context.Request.Query["culture"]; if (!string.IsNullOrWhiteSpace(cultureQuery)) { var culture = new CultureInfo(cultureQuery); CultureInfo.CurrentCulture = culture; CultureInfo.CurrentUICulture = culture; } return this._next(context); } }
以下代码展示了如何通过IApplicationBuilder的扩展方法暴露中间件:
public static class RequestCultureMiddlewareExtensions { public static IApplicationBuilder UseRequestCulture(this IApplicationBuilder builder) { return builder.UseMiddleware(); } }
以下代码从 「Configure」 调用中间件:
app.UseRequestCulture(); 每个请求的依赖关系 由于中间件是在应用程序启动时构建的,而不是每次请求时重新创建,因此中间件构造函数中注入的服务不会与其他依赖注入类型共享生命周期。如果你需要在中间件和其他类型之间共享作用域服务,请将这些服务添加到 Invoke 方法的签名中。Invoke 方法可以接受由依赖注入填充的其他参数。例如:
public class MyMiddleware { private readonly RequestDelegate _next; public MyMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext httpContext, IMyScopedService svc) { svc.MyProperty = 1000; await _next(httpContext); } }
你的点赞分享是对我最大的支持,点个再看呗!