.NET Core WebAPI 中间件与过滤器Filter深度剖析从原理到实战你是否曾经困惑过中间件和过滤器都能处理HTTP请求它们到底有什么区别什么时候该用中间件什么时候该用过滤器本文将带你彻底搞清楚这两个概念并通过实际案例让你轻松掌握。写在前面作为.NET开发者我们每天都在和HTTP请求打交道。在ASP.NET Core中处理请求有两个重要的概念中间件Middleware和过滤器Filter。很多初学者甚至一些有经验的开发者对它们的区别和使用场景都存在模糊认识。记得我刚接触ASP.NET Core时也曾被这两个概念搞晕。经过多年实践我总结了一套通俗易懂的理解方式。今天就让我用最直白的语言配合实际案例帮你彻底搞懂它们。一、概念解析1. 中间件Middleware中间件是ASP.NET Core请求处理管道中的一个个关卡。每个中间件都可以在请求到达后续中间件之前执行一些操作决定是否将请求传递给下一个中间件在后续中间件处理完成后执行一些操作可以把它想象成一个洋葱模型请求 → [中间件1] → [中间件2] → [中间件3] → 处理程序 ← [中间件3] ← [中间件2] ← [中间件1] ← 响应2. 过滤器Filter过滤器是MVC框架层面的概念它依附于控制器和Action方法。过滤器允许你在Action执行的不同阶段插入自定义逻辑。ASP.NET Core提供了五种类型的过滤器过滤器类型执行时机Authorization Filter授权验证最早执行Resource Filter资源处理前后模型绑定之前/之后Action FilterAction方法执行前后Exception Filter异常处理Result Filter结果执行前后二、核心区别为了让你更清晰地理解我整理了一个对比表格对比维度中间件过滤器所属层级管道级别全局MVC框架级别作用范围所有请求特定Controller/Action访问上下文只能访问HttpContext可以访问MVC上下文ModelState、Action参数等适用场景通用HTTP处理认证、日志、静态文件等业务逻辑处理参数验证、结果格式化等执行顺序按注册顺序按过滤器类型和Order属性是否依赖MVC否是一句话总结中间件管管道过滤器管业务中间件处理所有进入管道的请求不管你是访问API还是静态文件过滤器只处理MVC相关的请求Controller/Action关注业务逻辑的横切关注点三、深入源码分析中间件的工作原理中间件的本质是一个委托链。看一下UseMiddleware的简化实现publicclassApplicationBuilder{privatereadonlyListFuncRequestDelegate,RequestDelegate_componentsnew();publicIApplicationBuilderUse(FuncRequestDelegate,RequestDelegatemiddleware){_components.Add(middleware);returnthis;}publicRequestDelegateBuild(){RequestDelegateappcontext{context.Response.StatusCode404;returnTask.CompletedTask;};// 反向构建委托链foreach(varcomponentin_components.AsEnumerable().Reverse()){appcomponent(app);}returnapp;}}每个中间件都接收一个RequestDelegate下一个中间件并返回一个新的RequestDelegate。过滤器的执行流程过滤器的执行依赖于MVC的ActionInvoker。当请求到达MVC中间件后路由匹配到对应的Controller和Action然后ActionInvoker会执行Authorization Filter执行Resource FilterOnResourceExecuting执行Action FilterOnActionExecuting执行Action方法执行Action FilterOnActionExecuted执行Result FilterOnResultExecuting执行结果执行Result FilterOnResultExecuted执行Resource FilterOnResourceExecuted四、实战案例案例1全局异常处理使用中间件实现publicclassExceptionHandlingMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyILoggerExceptionHandlingMiddleware_logger;publicExceptionHandlingMiddleware(RequestDelegatenext,ILoggerExceptionHandlingMiddlewarelogger){_nextnext;_loggerlogger;}publicasyncTaskInvokeAsync(HttpContextcontext){try{await_next(context);}catch(Exceptionex){_logger.LogError(ex,请求处理发生异常);context.Response.StatusCodeStatusCodes.Status500InternalServerError;context.Response.ContentTypeapplication/json;varresponsenew{Successfalse,Message服务器内部错误,TraceIdcontext.TraceIdentifier};awaitcontext.Response.WriteAsync(JsonSerializer.Serialize(response));}}}// 注册方式app.UseMiddlewareExceptionHandlingMiddleware();使用过滤器实现publicclassGlobalExceptionFilter:IExceptionFilter{privatereadonlyILoggerGlobalExceptionFilter_logger;publicGlobalExceptionFilter(ILoggerGlobalExceptionFilterlogger){_loggerlogger;}publicvoidOnException(ExceptionContextcontext){_logger.LogError(context.Exception,Action执行发生异常);context.ResultnewObjectResult(new{Successfalse,Messagecontext.Exception.Message,// 开发环境可以返回具体信息StackTracecontext.Exception.StackTrace}){StatusCodeStatusCodes.Status500InternalServerError};context.ExceptionHandledtrue;}}// 注册方式builder.Services.AddControllers(options{options.Filters.AddGlobalExceptionFilter();});对比分析中间件的异常处理更底层会捕获所有请求包括静态文件的异常过滤器的异常处理只针对MVC请求但可以访问MVC上下文比如获取Action参数案例2请求/响应日志记录使用中间件实现publicclassRequestLoggingMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyILoggerRequestLoggingMiddleware_logger;publicRequestLoggingMiddleware(RequestDelegatenext,ILoggerRequestLoggingMiddlewarelogger){_nextnext;_loggerlogger;}publicasyncTaskInvokeAsync(HttpContextcontext){// 记录请求信息varrequestcontext.Request;varrequestBodyawaitReadRequestBodyAsync(request);_logger.LogInformation(请求路径: {Path}, 方法: {Method}, Body: {Body},request.Path,request.Method,requestBody);// 记录响应信息varoriginalBodyStreamcontext.Response.Body;usingvarresponseBodyStreamnewMemoryStream();context.Response.BodyresponseBodyStream;await_next(context);context.Response.Body.Seek(0,SeekOrigin.Begin);varresponseBodyawaitnewStreamReader(context.Response.Body).ReadToEndAsync();context.Response.Body.Seek(0,SeekOrigin.Begin);_logger.LogInformation(响应状态码: {StatusCode}, Body: {Body},context.Response.StatusCode,responseBody);awaitresponseBodyStream.CopyToAsync(originalBodyStream);}privateasyncTaskstringReadRequestBodyAsync(HttpRequestrequest){request.EnableBuffering();varbodyawaitnewStreamReader(request.Body).ReadToEndAsync();request.Body.Seek(0,SeekOrigin.Begin);returnbody;}}使用过滤器实现publicclassActionLoggingFilter:IActionFilter{privatereadonlyILoggerActionLoggingFilter_logger;publicActionLoggingFilter(ILoggerActionLoggingFilterlogger){_loggerlogger;}publicvoidOnActionExecuting(ActionExecutingContextcontext){varcontrollerNamecontext.Controller.GetType().Name;varactionNamecontext.ActionDescriptor.DisplayName;varparameterscontext.ActionArguments;_logger.LogInformation(执行Action: {Controller}.{Action}, 参数: {Parameters},controllerName,actionName,parameters);}publicvoidOnActionExecuted(ActionExecutedContextcontext){varcontrollerNamecontext.Controller.GetType().Name;varactionNamecontext.ActionDescriptor.DisplayName;if(context.Exception!null){_logger.LogError(context.Exception,Action执行失败);}else{varresultcontext.Result;_logger.LogInformation(Action执行成功: {Controller}.{Action}, 结果: {Result},controllerName,actionName,result);}}}对比分析中间件可以记录完整的请求和响应内容包括HTTP头、Body等过滤器只能记录MVC层面信息但可以访问Action参数模型记录更业务化的日志案例3接口权限验证使用中间件实现JWT验证publicclassJwtAuthenticationMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyIConfiguration_configuration;publicJwtAuthenticationMiddleware(RequestDelegatenext,IConfigurationconfiguration){_nextnext;_configurationconfiguration;}publicasyncTaskInvokeAsync(HttpContextcontext){// 白名单路径跳过验证varpathcontext.Request.Path.Value;if(path/api/auth/login||path/api/auth/register){await_next(context);return;}vartokencontext.Request.Headers[Authorization].FirstOrDefault()?.Replace(Bearer ,);if(string.IsNullOrEmpty(token)){context.Response.StatusCodeStatusCodes.Status401Unauthorized;awaitcontext.Response.WriteAsync(缺少认证Token);return;}try{// 验证JWT Token...await_next(context);}catch(Exception){context.Response.StatusCodeStatusCodes.Status401Unauthorized;awaitcontext.Response.WriteAsync(无效的Token);}}}使用过滤器实现自定义权限验证publicclassPermissionFilter:IAuthorizationFilter{privatereadonlystring_requiredPermission;publicPermissionFilter(stringrequiredPermission){_requiredPermissionrequiredPermission;}publicvoidOnAuthorization(AuthorizationFilterContextcontext){varusercontext.HttpContext.User;if(!user.Identity.IsAuthenticated){context.ResultnewUnauthorizedResult();return;}// 获取用户权限列表varpermissionsuser.Claims.Where(cc.TypePermission).Select(cc.Value).ToList();if(!permissions.Contains(_requiredPermission)){context.ResultnewForbidResult();return;}}}// 使用方式[PermissionFilter(User.Delete)][HttpDelete({id})]publicasyncTaskIActionResultDeleteUser(intid){// 只有拥有User.Delete权限的用户才能执行}对比分析中间件适合做统一的认证如JWT验证针对所有请求过滤器适合做细粒度的授权可以针对不同的Action配置不同的权限要求五、最佳实践指南什么时候使用中间件✅适合中间件的场景跨所有请求的通用处理认证、日志、异常捕获处理静态文件压缩/加密请求和响应跨域处理CORS请求限流自定义路由❌不适合中间件的场景需要访问MVC特定功能ModelState、Action参数需要根据Controller/Action做差异化处理需要访问Action的返回值什么时候使用过滤器✅适合过滤器的场景Action参数的验证和预处理Action执行前后的业务逻辑统一的结果格式化细粒度的权限控制缓存控制事务管理如EF Core的事务❌不适合过滤器的场景处理非MVC请求如静态文件需要在整个管道层面做处理处理原始HTTP请求/响应流执行顺序的注意事项注册顺序很重要举个实际例子// Program.csvarappbuilder.Build();// 1. 异常处理中间件最先注册最后执行app.UseMiddlewareExceptionHandlingMiddleware();// 2. 认证中间件app.UseMiddlewareAuthenticationMiddleware();// 3. 日志中间件app.UseMiddlewareLoggingMiddleware();// 4. MVC中间件最后注册最先执行app.MapControllers();app.Run();执行顺序日志 → 认证 → 异常处理 → 请求 → 异常处理返回→ 认证返回→ 日志返回六、进阶技巧1. 中间件和过滤器的结合使用实际项目中我通常这样组合使用// 中间件处理全局异常、JWT认证、请求日志app.UseMiddlewareExceptionHandlingMiddleware();app.UseMiddlewareJwtAuthenticationMiddleware();app.UseMiddlewareRequestLoggingMiddleware();// 过滤器处理权限验证、参数校验、事务管理builder.Services.AddControllers(options{options.Filters.AddPermissionFilter();options.Filters.AddValidationFilter();options.Filters.AddTransactionFilter();});2. 自定义中间件的最佳实践// 推荐使用扩展方法简化注册publicstaticclassMiddlewareExtensions{publicstaticIApplicationBuilderUseCustomAuth(thisIApplicationBuilderapp){returnapp.UseMiddlewareCustomAuthMiddleware();}}// 使用app.UseCustomAuth();3. 依赖注入的区别中间件通过构造函数注入生命周期为Singleton或ScopedInvoke方法参数可以获取Scoped服务过滤器可以通过ServiceFilter或TypeFilter属性注入支持更灵活的DI// 中间件获取Scoped服务publicasyncTaskInvokeAsync(HttpContextcontext,IUserServiceuserService){// userService 是Scoped生命周期}// 过滤器使用ServiceFilter[ServiceFilter(typeof(UserService))]publicclassUserController:ControllerBase{// 自动注入}七、总结核心要点本质区别中间件在管道层面工作过滤器在MVC框架层面工作作用范围中间件影响所有请求过滤器只影响MVC请求使用场景中间件做管道的事过滤器做业务的事执行顺序中间件按注册顺序执行过滤器有固定的生命周期顺序快速决策表需求推荐方案统一异常处理都可以范围广用中间件需要MVC上下文用过滤器JWT认证中间件细粒度权限控制过滤器Authorization Filter请求日志中间件记录原始数据Action参数验证过滤器Action Filter跨域处理中间件响应缓存过滤器Result Filter处理静态文件中间件一句话记忆中间件是管道工负责整个HTTP管道的疏通过滤器是质检员负责MVC业务环节的品质把控。希望这篇文章能帮你彻底理解中间件和过滤器的区别。在实际开发中选择合适的工具能让你的代码更优雅、更高效。如果还有其他疑问欢迎在评论区交流讨论下期预告我们将深入探讨如何在ASP.NET Core中实现优雅的全局事务管理敬请期待如果你觉得这篇文章对你有帮助欢迎点赞、收藏、分享你的支持是我持续创作的动力。
.NET Core WebAPI 中间件与过滤器(Filter)深度剖析:从原理到实战
.NET Core WebAPI 中间件与过滤器Filter深度剖析从原理到实战你是否曾经困惑过中间件和过滤器都能处理HTTP请求它们到底有什么区别什么时候该用中间件什么时候该用过滤器本文将带你彻底搞清楚这两个概念并通过实际案例让你轻松掌握。写在前面作为.NET开发者我们每天都在和HTTP请求打交道。在ASP.NET Core中处理请求有两个重要的概念中间件Middleware和过滤器Filter。很多初学者甚至一些有经验的开发者对它们的区别和使用场景都存在模糊认识。记得我刚接触ASP.NET Core时也曾被这两个概念搞晕。经过多年实践我总结了一套通俗易懂的理解方式。今天就让我用最直白的语言配合实际案例帮你彻底搞懂它们。一、概念解析1. 中间件Middleware中间件是ASP.NET Core请求处理管道中的一个个关卡。每个中间件都可以在请求到达后续中间件之前执行一些操作决定是否将请求传递给下一个中间件在后续中间件处理完成后执行一些操作可以把它想象成一个洋葱模型请求 → [中间件1] → [中间件2] → [中间件3] → 处理程序 ← [中间件3] ← [中间件2] ← [中间件1] ← 响应2. 过滤器Filter过滤器是MVC框架层面的概念它依附于控制器和Action方法。过滤器允许你在Action执行的不同阶段插入自定义逻辑。ASP.NET Core提供了五种类型的过滤器过滤器类型执行时机Authorization Filter授权验证最早执行Resource Filter资源处理前后模型绑定之前/之后Action FilterAction方法执行前后Exception Filter异常处理Result Filter结果执行前后二、核心区别为了让你更清晰地理解我整理了一个对比表格对比维度中间件过滤器所属层级管道级别全局MVC框架级别作用范围所有请求特定Controller/Action访问上下文只能访问HttpContext可以访问MVC上下文ModelState、Action参数等适用场景通用HTTP处理认证、日志、静态文件等业务逻辑处理参数验证、结果格式化等执行顺序按注册顺序按过滤器类型和Order属性是否依赖MVC否是一句话总结中间件管管道过滤器管业务中间件处理所有进入管道的请求不管你是访问API还是静态文件过滤器只处理MVC相关的请求Controller/Action关注业务逻辑的横切关注点三、深入源码分析中间件的工作原理中间件的本质是一个委托链。看一下UseMiddleware的简化实现publicclassApplicationBuilder{privatereadonlyListFuncRequestDelegate,RequestDelegate_componentsnew();publicIApplicationBuilderUse(FuncRequestDelegate,RequestDelegatemiddleware){_components.Add(middleware);returnthis;}publicRequestDelegateBuild(){RequestDelegateappcontext{context.Response.StatusCode404;returnTask.CompletedTask;};// 反向构建委托链foreach(varcomponentin_components.AsEnumerable().Reverse()){appcomponent(app);}returnapp;}}每个中间件都接收一个RequestDelegate下一个中间件并返回一个新的RequestDelegate。过滤器的执行流程过滤器的执行依赖于MVC的ActionInvoker。当请求到达MVC中间件后路由匹配到对应的Controller和Action然后ActionInvoker会执行Authorization Filter执行Resource FilterOnResourceExecuting执行Action FilterOnActionExecuting执行Action方法执行Action FilterOnActionExecuted执行Result FilterOnResultExecuting执行结果执行Result FilterOnResultExecuted执行Resource FilterOnResourceExecuted四、实战案例案例1全局异常处理使用中间件实现publicclassExceptionHandlingMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyILoggerExceptionHandlingMiddleware_logger;publicExceptionHandlingMiddleware(RequestDelegatenext,ILoggerExceptionHandlingMiddlewarelogger){_nextnext;_loggerlogger;}publicasyncTaskInvokeAsync(HttpContextcontext){try{await_next(context);}catch(Exceptionex){_logger.LogError(ex,请求处理发生异常);context.Response.StatusCodeStatusCodes.Status500InternalServerError;context.Response.ContentTypeapplication/json;varresponsenew{Successfalse,Message服务器内部错误,TraceIdcontext.TraceIdentifier};awaitcontext.Response.WriteAsync(JsonSerializer.Serialize(response));}}}// 注册方式app.UseMiddlewareExceptionHandlingMiddleware();使用过滤器实现publicclassGlobalExceptionFilter:IExceptionFilter{privatereadonlyILoggerGlobalExceptionFilter_logger;publicGlobalExceptionFilter(ILoggerGlobalExceptionFilterlogger){_loggerlogger;}publicvoidOnException(ExceptionContextcontext){_logger.LogError(context.Exception,Action执行发生异常);context.ResultnewObjectResult(new{Successfalse,Messagecontext.Exception.Message,// 开发环境可以返回具体信息StackTracecontext.Exception.StackTrace}){StatusCodeStatusCodes.Status500InternalServerError};context.ExceptionHandledtrue;}}// 注册方式builder.Services.AddControllers(options{options.Filters.AddGlobalExceptionFilter();});对比分析中间件的异常处理更底层会捕获所有请求包括静态文件的异常过滤器的异常处理只针对MVC请求但可以访问MVC上下文比如获取Action参数案例2请求/响应日志记录使用中间件实现publicclassRequestLoggingMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyILoggerRequestLoggingMiddleware_logger;publicRequestLoggingMiddleware(RequestDelegatenext,ILoggerRequestLoggingMiddlewarelogger){_nextnext;_loggerlogger;}publicasyncTaskInvokeAsync(HttpContextcontext){// 记录请求信息varrequestcontext.Request;varrequestBodyawaitReadRequestBodyAsync(request);_logger.LogInformation(请求路径: {Path}, 方法: {Method}, Body: {Body},request.Path,request.Method,requestBody);// 记录响应信息varoriginalBodyStreamcontext.Response.Body;usingvarresponseBodyStreamnewMemoryStream();context.Response.BodyresponseBodyStream;await_next(context);context.Response.Body.Seek(0,SeekOrigin.Begin);varresponseBodyawaitnewStreamReader(context.Response.Body).ReadToEndAsync();context.Response.Body.Seek(0,SeekOrigin.Begin);_logger.LogInformation(响应状态码: {StatusCode}, Body: {Body},context.Response.StatusCode,responseBody);awaitresponseBodyStream.CopyToAsync(originalBodyStream);}privateasyncTaskstringReadRequestBodyAsync(HttpRequestrequest){request.EnableBuffering();varbodyawaitnewStreamReader(request.Body).ReadToEndAsync();request.Body.Seek(0,SeekOrigin.Begin);returnbody;}}使用过滤器实现publicclassActionLoggingFilter:IActionFilter{privatereadonlyILoggerActionLoggingFilter_logger;publicActionLoggingFilter(ILoggerActionLoggingFilterlogger){_loggerlogger;}publicvoidOnActionExecuting(ActionExecutingContextcontext){varcontrollerNamecontext.Controller.GetType().Name;varactionNamecontext.ActionDescriptor.DisplayName;varparameterscontext.ActionArguments;_logger.LogInformation(执行Action: {Controller}.{Action}, 参数: {Parameters},controllerName,actionName,parameters);}publicvoidOnActionExecuted(ActionExecutedContextcontext){varcontrollerNamecontext.Controller.GetType().Name;varactionNamecontext.ActionDescriptor.DisplayName;if(context.Exception!null){_logger.LogError(context.Exception,Action执行失败);}else{varresultcontext.Result;_logger.LogInformation(Action执行成功: {Controller}.{Action}, 结果: {Result},controllerName,actionName,result);}}}对比分析中间件可以记录完整的请求和响应内容包括HTTP头、Body等过滤器只能记录MVC层面信息但可以访问Action参数模型记录更业务化的日志案例3接口权限验证使用中间件实现JWT验证publicclassJwtAuthenticationMiddleware{privatereadonlyRequestDelegate_next;privatereadonlyIConfiguration_configuration;publicJwtAuthenticationMiddleware(RequestDelegatenext,IConfigurationconfiguration){_nextnext;_configurationconfiguration;}publicasyncTaskInvokeAsync(HttpContextcontext){// 白名单路径跳过验证varpathcontext.Request.Path.Value;if(path/api/auth/login||path/api/auth/register){await_next(context);return;}vartokencontext.Request.Headers[Authorization].FirstOrDefault()?.Replace(Bearer ,);if(string.IsNullOrEmpty(token)){context.Response.StatusCodeStatusCodes.Status401Unauthorized;awaitcontext.Response.WriteAsync(缺少认证Token);return;}try{// 验证JWT Token...await_next(context);}catch(Exception){context.Response.StatusCodeStatusCodes.Status401Unauthorized;awaitcontext.Response.WriteAsync(无效的Token);}}}使用过滤器实现自定义权限验证publicclassPermissionFilter:IAuthorizationFilter{privatereadonlystring_requiredPermission;publicPermissionFilter(stringrequiredPermission){_requiredPermissionrequiredPermission;}publicvoidOnAuthorization(AuthorizationFilterContextcontext){varusercontext.HttpContext.User;if(!user.Identity.IsAuthenticated){context.ResultnewUnauthorizedResult();return;}// 获取用户权限列表varpermissionsuser.Claims.Where(cc.TypePermission).Select(cc.Value).ToList();if(!permissions.Contains(_requiredPermission)){context.ResultnewForbidResult();return;}}}// 使用方式[PermissionFilter(User.Delete)][HttpDelete({id})]publicasyncTaskIActionResultDeleteUser(intid){// 只有拥有User.Delete权限的用户才能执行}对比分析中间件适合做统一的认证如JWT验证针对所有请求过滤器适合做细粒度的授权可以针对不同的Action配置不同的权限要求五、最佳实践指南什么时候使用中间件✅适合中间件的场景跨所有请求的通用处理认证、日志、异常捕获处理静态文件压缩/加密请求和响应跨域处理CORS请求限流自定义路由❌不适合中间件的场景需要访问MVC特定功能ModelState、Action参数需要根据Controller/Action做差异化处理需要访问Action的返回值什么时候使用过滤器✅适合过滤器的场景Action参数的验证和预处理Action执行前后的业务逻辑统一的结果格式化细粒度的权限控制缓存控制事务管理如EF Core的事务❌不适合过滤器的场景处理非MVC请求如静态文件需要在整个管道层面做处理处理原始HTTP请求/响应流执行顺序的注意事项注册顺序很重要举个实际例子// Program.csvarappbuilder.Build();// 1. 异常处理中间件最先注册最后执行app.UseMiddlewareExceptionHandlingMiddleware();// 2. 认证中间件app.UseMiddlewareAuthenticationMiddleware();// 3. 日志中间件app.UseMiddlewareLoggingMiddleware();// 4. MVC中间件最后注册最先执行app.MapControllers();app.Run();执行顺序日志 → 认证 → 异常处理 → 请求 → 异常处理返回→ 认证返回→ 日志返回六、进阶技巧1. 中间件和过滤器的结合使用实际项目中我通常这样组合使用// 中间件处理全局异常、JWT认证、请求日志app.UseMiddlewareExceptionHandlingMiddleware();app.UseMiddlewareJwtAuthenticationMiddleware();app.UseMiddlewareRequestLoggingMiddleware();// 过滤器处理权限验证、参数校验、事务管理builder.Services.AddControllers(options{options.Filters.AddPermissionFilter();options.Filters.AddValidationFilter();options.Filters.AddTransactionFilter();});2. 自定义中间件的最佳实践// 推荐使用扩展方法简化注册publicstaticclassMiddlewareExtensions{publicstaticIApplicationBuilderUseCustomAuth(thisIApplicationBuilderapp){returnapp.UseMiddlewareCustomAuthMiddleware();}}// 使用app.UseCustomAuth();3. 依赖注入的区别中间件通过构造函数注入生命周期为Singleton或ScopedInvoke方法参数可以获取Scoped服务过滤器可以通过ServiceFilter或TypeFilter属性注入支持更灵活的DI// 中间件获取Scoped服务publicasyncTaskInvokeAsync(HttpContextcontext,IUserServiceuserService){// userService 是Scoped生命周期}// 过滤器使用ServiceFilter[ServiceFilter(typeof(UserService))]publicclassUserController:ControllerBase{// 自动注入}七、总结核心要点本质区别中间件在管道层面工作过滤器在MVC框架层面工作作用范围中间件影响所有请求过滤器只影响MVC请求使用场景中间件做管道的事过滤器做业务的事执行顺序中间件按注册顺序执行过滤器有固定的生命周期顺序快速决策表需求推荐方案统一异常处理都可以范围广用中间件需要MVC上下文用过滤器JWT认证中间件细粒度权限控制过滤器Authorization Filter请求日志中间件记录原始数据Action参数验证过滤器Action Filter跨域处理中间件响应缓存过滤器Result Filter处理静态文件中间件一句话记忆中间件是管道工负责整个HTTP管道的疏通过滤器是质检员负责MVC业务环节的品质把控。希望这篇文章能帮你彻底理解中间件和过滤器的区别。在实际开发中选择合适的工具能让你的代码更优雅、更高效。如果还有其他疑问欢迎在评论区交流讨论下期预告我们将深入探讨如何在ASP.NET Core中实现优雅的全局事务管理敬请期待如果你觉得这篇文章对你有帮助欢迎点赞、收藏、分享你的支持是我持续创作的动力。