ASP.NET Core中的资源筛选器是什么?如何创建?

来源:Nodejs社区作者:会飞的猪头衔:草根站长
导读:本期聚焦于会飞的猪创作的《ASP.NET Core中的资源筛选器是什么?如何创建?》,敬请观看详情。ASP.NET Core的请求处理管道中,资源筛选器是少数能在模型绑定之前执行并在Action执行之前短路管道的过滤器类型。它位于授权筛选器之后、模型绑定之前,承担着拦截请求、初始化共享资源、实现缓存命中和请求预处理等职责。当OnResourceExecuting方法设置了Result属性后,后续的模型绑定、Action执行和结果执行都会被跳过,响应直接返回客户端,这种特性非常适合对性能敏感的场景。创建一个资源筛选器并不复杂,核心步骤是让类实现IResourceFilter或IAsyncResourceFilter接口,分别实现同步或异步方法,再通过特性标注、TypeFilter、ServiceFilter或全局注册的方式将其挂载到MVC管道中。本文结合接口定义、执行时机、注册方式和典型应用场景,给出可运行的代码示例,帮助开发者快速掌握资源筛选器的创建与使用。

在ASP.NET Core MVC中,过滤器提供了在请求处理管道的不同阶段插入横切逻辑的机制。资源筛选器通常用于处理缓存、防盗链、资源初始化或者任何需要在模型绑定之前决定是否继续执行管道的逻辑。与其他筛选器相比,资源筛选器的关键特征是它在模型绑定之前运行,并且可以通过设置上下文中的Result属性来短路整个管道。这意味着一旦检测到缓存命中,Action方法根本不会执行,模型绑定也不会发生,服务端可以立即返回缓存内容。

ASP.NET Core中的资源筛选器是什么?如何创建?

资源筛选器在过滤器管道中的执行时机

ASP.NET Core MVC将过滤器分为多个阶段,执行顺序从外到内依次为授权筛选器、资源筛选器、模型绑定、Action筛选器、Action执行、异常筛选器、结果筛选器、结果执行。资源筛选器处于授权筛选器之后,但在模型绑定之前。这一位置赋予它两个重要能力:一是能够在模型绑定消耗资源之前拦截请求;二是能够像授权筛选器一样短路请求。

需要明确的是,资源筛选器的短路行为与授权筛选器并不冲突。授权筛选器负责身份验证和授权决策,通常在资源筛选器之前运行;资源筛选器更适合处理与资源本身相关的预处理逻辑,比如根据请求路径读取缓存、检查If-None-Match请求头,或者初始化一个必须贯穿后续Action执行的共享对象。理解执行顺序有助于避免在资源筛选器中重复读取请求体,因为模型绑定还没有开始,此时读取请求体可能干扰后续Action的参数绑定。

从生命周期来看,资源筛选器在Action执行前触发一次,在Action执行后触发一次。同步接口通过OnResourceExecuting和OnResourceExecuted两个方法实现;异步接口通过一个包含委托的方法实现。无论使用哪种方式,资源筛选器都能访问完整的ResourceExecutingContext和ResourceExecutedContext,并可通过它们获取HttpContext、路由数据、模型状态以及Result等信息。

同步与异步接口的实现方式

ASP.NET Core为资源筛选器提供了两个接口:IResourceFilterIAsyncResourceFilter。同步接口适合逻辑简单、不涉及异步IO的场景,异步接口适合需要访问数据库、分布式缓存或外部HTTP服务的场景。两个接口可以同时实现,但框架会优先使用异步接口。开发时应根据实际需要只实现其中一个,避免同时实现导致执行顺序混乱。

下面是实现同步资源筛选器的完整示例。该类通过构造函数注入ILogger,并且在执行前记录日志,在执行后清理资源。代码中的ResourceExecutingContext和ResourceExecutedContext对象由框架创建并传入。

public class LoggingResourceFilter : IResourceFilter
{
    private readonly ILogger<LoggingResourceFilter> _logger;

    public LoggingResourceFilter(ILogger<LoggingResourceFilter> logger)
    {
        _logger = logger;
    }

    public void OnResourceExecuting(ResourceExecutingContext context)
    {
        _logger.LogInformation("资源筛选器开始执行,请求路径:{Path}", context.HttpContext.Request.Path);
    }

    public void OnResourceExecuted(ResourceExecutedContext context)
    {
        _logger.LogInformation("资源筛选器执行完成,是否存在异常:{HasException}", context.Exception != null);
    }
}

异步资源筛选器使用ResourceExecutionDelegate委托来调用管道中的下一个阶段。调用next()之前编写执行前逻辑,调用之后编写执行后逻辑。需要注意的是,如果决定短路管道,就不应再调用next(),否则仍然会继续执行后续阶段。

public class ShortCircuitResourceFilter : IAsyncResourceFilter
{
    public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
    {
        if (context.HttpContext.Request.Headers.ContainsKey("X-Skip-Action"))
        {
            context.Result = new ContentResult
            {
                Content = "请求已被资源筛选器短路,Action不会执行。",
                ContentType = "text/plain",
                StatusCode = 200
            };
            return;
        }

        await next();
    }
}

这个示例展示了资源筛选器最经典的用法:执行前检查请求条件,命中则设置Result并直接返回;未命中则继续执行后续管道。由于资源筛选器在模型绑定之前执行,这种短路操作可以完全避免模型绑定和Action执行的开销。

注册资源筛选器的几种方式

创建好的资源筛选器必须注册到MVC管道中才能生效。ASP.NET Core提供了四种常见的注册方式:通过特性标注到Controller或Action、通过TypeFilter特性、通过ServiceFilter特性、以及通过全局过滤器配置。

如果筛选器不需要依赖注入,可以直接以特性形式使用。例如定义一个继承自Attribute并实现IResourceFilter的类,然后标注在Controller或Action上。但如果筛选器需要通过构造函数注入服务,就不能简单使用特性实例化,因为特性参数必须是编译期常量。这时候需要使用TypeFilter或ServiceFilter。

[TypeFilter(typeof(LoggingResourceFilter))]
public class ProductsController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

TypeFilter会根据注册的服务创建筛选器实例,并将服务容器中的依赖注入到构造函数中。它不需要预先在服务容器中注册筛选器类型。ServiceFilter与之类似,但要求筛选器类型必须预先在Startup或Program文件中注册。全局注册则适用于所有请求都需要经过的资源筛选器。

builder.Services.AddControllers(options =>
{
    options.Filters.Add<LoggingResourceFilter>();
});

在实际项目中,如果需要按特定顺序执行多个资源筛选器,可以通过实现IOrderedFilter接口并设置Order属性来控制顺序。资源筛选器的执行顺序还受注册位置影响,全局筛选器先于Controller和Action上的筛选器执行。理解这些细节可以避免缓存逻辑和日志逻辑之间出现意外干扰。

短路响应与典型应用场景

资源筛选器最强大的特性之一就是短路响应。当OnResourceExecuting或OnResourceExecutionAsync的执行前逻辑设置了context.Result,后续的模型绑定、Action执行和Result执行都会被跳过,MVC会直接执行Result对象来生成响应。这意味着可以在请求到达业务代码之前就返回结果,非常适合缓存命中、频繁访问的静态资源处理、防盗链验证以及限流等场景。

除了缓存,资源筛选器还适合处理本地化设置。例如在请求进入Action之前读取语言偏好cookie或请求头,将CultureInfo写入当前线程,从而让后续的数据格式化和视图渲染使用正确的语言环境。也可以利用资源筛选器的一次性资源包装能力,在执行前打开数据库连接、创建日志作用域,在执行后释放非托管资源。

需要注意的是,资源筛选器虽然灵活,但不应滥用。如果设置短路响应后仍然有部分逻辑需要执行,应考虑使用结果筛选器或中间件。资源筛选器与中间件在功能上有一定重叠,但资源筛选器运行在MVC框架内部,能够使用路由数据和Action上下文等信息,这是中间件不具备的优势。根据具体场景选择合适的扩展点,可以保证请求管道清晰且性能可控。

ASP.NET Core资源筛选器IResourceFilter修改时间:2026-08-29 22:04:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。