ASP.NET Core 中间件
文章目录
- 前言
- 一、中间件的本质
- 定义:
- 类比:
- 二、作用场景:
- 三、中间件的执行顺序
- 四、中间件的配置方式
- 1)委托形式(最常见):
- 2)类形式:
- 五、核心方法
- 六、注意事项
- 七、中间件 vs 过滤器(Filter)
- 总结
前言
ASP.NET Core 中间件是构成请求处理管道的核心组件,用于处理 HTTP 请求和响应。
一、中间件的本质
定义:
- 中间件是按顺序执行的组件,串联成请求处理管道(Pipeline),每个组件负责处理请求或响应的特定阶段。
类比:
- 类似工厂流水线,每个工位(中间件)对请求进行加工,最终生成响应。
二、作用场景:
- 典型场景:
- 身份验证/授权(如 UseAuthentication)
- 静态文件处理(如 UseStaticFiles)
- 异常处理(如 UseExceptionHandler)
- 日志记录、请求日志
- 路由匹配(如 UseRouting)
- 自定义业务逻辑(如缓存、请求改写)
三、中间件的执行顺序
- 关键规则:顺序至关重要,顺序决定行为,先注册的中间件先执行请求,后执行响应(类似栈结构)。
- 推荐顺序
app.UseExceptionHandler(); // 1. 通常放在管道最前端,确保后续中间件的异常被捕获。 app.UseHttpsRedirection(); // 2. HTTPS重定向 app.UseStaticFiles(); // 3. 若请求匹配静态文件,直接响应,终止后续中间件 app.UseRouting(); // 4. 路由解析 app.UseAuthentication(); // 5. 身份验证 app.UseAuthorization(); // 6. 授权 app.UseEndpoints(...); // 7. 终结点处理(如 MVC)
四、中间件的配置方式
1)委托形式(最常见):
- 示例
app.Map("/test", async midbuilder => {midbuilder.Use(async (context, next) => {context.Response.ContentType = "text/html";// 处理请求(如记录日志)await next.Invoke();// 调用下一个中间件// 处理响应(如修改响应头)});midbuilder.Use(async (context, next) => { // 处理请求await next.Invoke();// 调用下一个中间件// 处理响应});midbuilder.Run(async context => { await context.Response.WriteAsync("run<br/>");});});
2)类形式:
- 实现
public class RequestTimeMiddleware{private readonly RequestDelegate next;public RequestTimeMiddleware(RequestDelegate next){this.next = next;}public async Task InvokeAsync(HttpContext context){var start = DateTime.Now;await next(context);var duration = DateTime.Now - start;await context.Response.WriteAsync($"Time {duration.TotalMilliseconds}ms</br>");}}
- 注册中间件
app.UseMiddleware<RequestTimeMiddleware>();
五、核心方法
-
Use:添加可传递请求到下一个中间件的组件。
midbuilder.Use(async (context, next) => { // 处理请求await next.Invoke();// 调用下一个中间件// 处理响应});
-
UseWhen:根据条件动态选择中间件。
app.UseWhen(context => context.Request.Headers.ContainsKey("X-Custom-Header"), branch => branch.UseMiddleware<CustomHeaderMiddleware>());
-
Run:添加终止中间件(不调用 next)。
app.Run(async context => {await context.Response.WriteAsync("Hello World"); });
-
Map:根据请求路径分支管道。
app.Map("/admin", adminApp => {adminApp.UseAuthentication();adminApp.UseAuthorization(); });
-
完整示例
app.Map("/test", async midbuilder => {midbuilder.Use(async (context, next) => {context.Response.ContentType = "text/html";// 处理请求(如记录日志)await next.Invoke();// 调用下一个中间件// 处理响应(如修改响应头)});midbuilder.Use(async (context, next) => { // 处理请求await next.Invoke();// 调用下一个中间件// 处理响应});midbuilder.Run(async context => { await context.Response.WriteAsync("run<br/>");});});
六、注意事项
- 静态文件中间件应在路由前注册,避免路由匹配影响性能。
- 日志中间件若需记录完整处理时间,需放在异常处理之后,确保异常处理后的响应时间也被记录。
- 使用next()时,若后续中间件抛出异常,异常会向上冒泡到已执行过的中间件中,需合理使用try-catch。
七、中间件 vs 过滤器(Filter)
-
中间件:作用于整个请求管道,与 MVC 无关(更底层)。
-
过滤器:专为 MVC 设计,处理 Controller/Action 特定逻辑(如模型绑定、权限校验)。
总结
中间件是 ASP.NET Core 请求处理的核心机制,通过管道式设计实现高度模块化和灵活的 HTTP 处理逻辑。理解其顺序性和短路机制是构建高效应用的关键。