ASP.NET Core 中间件

文章目录


前言

ASP.NET Core 中间件是构成请求处理管道的核心组件,用于处理 HTTP 请求和响应。


一、中间件的本质

定义:

  • 中间件是按顺序执行的组件,串联成请求处理管道(Pipeline),每个组件负责处理请求或响应的特定阶段。

类比:

  • 类似工厂流水线,每个工位(中间件)对请求进行加工,最终生成响应。

二、作用场景:

  • 典型场景:
    • 身份验证/授权(如 UseAuthentication
    • 静态文件处理(如 UseStaticFiles
    • 异常处理(如 UseExceptionHandler
    • 日志记录、请求日志
    • 路由匹配(如 UseRouting
    • 自定义业务逻辑(如缓存、请求改写)

三、中间件的执行顺序

  • 关键规则 :顺序至关重要,顺序决定行为,先注册的中间件先执行请求,后执行响应(类似栈结构)。

  • 推荐顺序

    bash 复制代码
    app.UseExceptionHandler();    // 1. 通常放在管道最前端,确保后续中间件的异常被捕获。
    app.UseHttpsRedirection();	  // 2. HTTPS重定向
    app.UseStaticFiles();         // 3. 若请求匹配静态文件,直接响应,终止后续中间件
    app.UseRouting();            // 4. 路由解析
    app.UseAuthentication();      // 5. 身份验证
    app.UseAuthorization();		  // 6. 授权
    app.UseEndpoints(...);        // 7. 终结点处理(如 MVC)

四、中间件的配置方式

1)委托形式(最常见):

  • 示例

    bash 复制代码
    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)类形式:

  • 实现

    bash 复制代码
     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>");
      
         }
     }
  • 注册中间件

    bash 复制代码
    app.UseMiddleware<RequestTimeMiddleware>();

五、核心方法

  • Use:添加可传递请求到下一个中间件的组件。

    bash 复制代码
     midbuilder.Use(async (context, next) => {        
    	         // 处理请求
    	        await next.Invoke();// 调用下一个中间件
    	        // 处理响应
    	    });
  • UseWhen:根据条件动态选择中间件。

    bash 复制代码
    app.UseWhen(context => context.Request.Headers.ContainsKey("X-Custom-Header"), 
    branch => branch.UseMiddleware<CustomHeaderMiddleware>());
  • Run :添加终止中间件(不调用 next)。

    bash 复制代码
    app.Run(async context => 
    {
        await context.Response.WriteAsync("Hello World");
    });
  • Map:根据请求路径分支管道。

    bash 复制代码
    app.Map("/admin", adminApp =>
    {
        adminApp.UseAuthentication();
        adminApp.UseAuthorization();
    });
  • 完整示例

    bash 复制代码
    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 处理逻辑。理解其顺序性和短路机制是构建高效应用的关键。

相关推荐
优创学社21 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
why技术1 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理1 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
ai小鬼头2 小时前
AIStarter如何助力用户与创作者?Stable Diffusion一键管理教程!
后端·架构·github
简佐义的博客2 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
失败又激情的man3 小时前
Scrapy进阶封装(第四阶段:中间件设置,动态UA,ip代理池)
爬虫·scrapy·中间件
Code blocks3 小时前
使用Jenkins完成springboot项目快速更新
java·运维·spring boot·后端·jenkins
追逐时光者3 小时前
一款开源免费、通用的 WPF 主题控件包
后端·.net