You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET中如何获取控制器方法上已应用的UserAuthFilter实例?

问题描述

我定义了如下自定义过滤器:

public class UserAuthFilter : ActionFilterAttribute, IActionFilter
{
   public bool AllowAnonymous { get; set; } = false;
   public string Name { get; set; };
   
   public UserAuthFilter(bool allowAnonymous = false, string name = "") 
   {
      this.AllowAnonymous = allowAnonymous;
      this.Name = name;
   }
 
   public async override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
   {
        // some actions
        await next();
   }
}

并将其应用在控制器的方法上:

[HttpPost]
[UserAuthFilter]
public async Task<IActionResult> Create(CreateDataRequest request)
{
    //
    // 此处希望获取当前应用的UserAuthFilter实例
    //
    return service.Create(request);
}

请问是否可以在上述注释位置获取到已应用的过滤器实例?我曾尝试将属性设为静态变量,通过UserAuthFilter.AllowAnonymous静态访问,但该方案并不合适。

解决方案

可以获取到,推荐两种可靠的实现方式:

方式一:通过HttpContext传递过滤器实例

修改过滤器的OnActionExecutionAsync方法,将当前实例存入请求的HttpContext.Items集合,控制器方法即可直接读取:

public async override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
    // 将当前过滤器实例存入HttpContext
    context.HttpContext.Items["CurrentUserAuthFilter"] = this;
    await next();
}

控制器方法中读取:

[HttpPost]
[UserAuthFilter]
public async Task<IActionResult> Create(CreateDataRequest request)
{
    if (HttpContext.Items.TryGetValue("CurrentUserAuthFilter", out var filterObj) && filterObj is UserAuthFilter filter)
    {
        // 成功获取当前过滤器实例,可访问其属性
        var isAllowAnonymous = filter.AllowAnonymous;
        var filterName = filter.Name;
    }
    return service.Create(request);
}

方式二:从ActionDescriptor中筛选过滤器实例

通过ControllerContext获取当前Action的描述符,从中筛选出目标过滤器实例:

[HttpPost]
[UserAuthFilter]
public async Task<IActionResult> Create(CreateDataRequest request)
{
    var filter = ControllerContext.ActionDescriptor.FilterDescriptors
        .Select(descriptor => descriptor.Filter)
        .OfType<UserAuthFilter>()
        .FirstOrDefault();
    
    if (filter != null)
    {
        // 成功获取过滤器实例
        var filterName = filter.Name;
    }
    return service.Create(request);
}

关键说明

  • 方式一能确保拿到当前请求对应的过滤器实例,因为默认情况下ActionFilterAttribute会为每个请求创建新实例(除非配置了复用策略);
  • 方式二若过滤器应用在控制器级别,需扩展筛选逻辑,同时检查控制器的过滤器集合;
  • 静态变量方案不可取,全局共享的静态变量会在多请求并发时出现数据错乱问题。

内容的提问来源于stack exchange,提问作者honneq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:01:13