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

如何访问ActionFilter内部属性并在控制器中使用其值

实现方案

你可以通过HttpContext.Items做单次请求内的参数传递,这是成本最低、最简洁的实现方式,同时先修正你原代码中User无上下文引用的小问题,完整实现如下:


第一步:修改LogAttribute代码,存入公共上下文

public class LogAttribute : ActionFilterAttribute
{
    public LogAttribute(ILoggerFactory logger)
    {
        Logger = logger.CreateLogger<LogAttribute>();
    }

    public ILogger Logger { get; }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // 修正原代码的User引用错误,从当前请求上下文取用户信息
        var userId = context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
        var path = $"{context.HttpContext.Request.Path.Value}[{context.HttpContext.Request.Method}]";
        
        Logger.LogDebug($"{path} started. User(id): {userId}.");
        
        // 存入HttpContext.Items,单次请求生命周期内全局可访问
        context.HttpContext.Items["Log_UserId"] = userId;
        context.HttpContext.Items["Log_Path"] = path;
    }
}

第二步:控制器中取值的两种用法

用法1:直接取值(无需额外封装)

只要控制器/对应Action加了[Log]特性,直接在任意位置读取即可:

[Log]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        var userId = HttpContext.Items["Log_UserId"] as string;
        var path = HttpContext.Items["Log_Path"] as string;
        // 直接使用两个参数即可
        return View();
    }
}
用法2:基类封装(更简洁,全局复用)

如果多个控制器都要用到这两个参数,可以封装到控制器基类里,直接当属性调用:

// 统一封装基类
public class BaseController : Controller
{
    protected string LogUserId => HttpContext.Items["Log_UserId"] as string;
    protected string LogPath => HttpContext.Items["Log_Path"] as string;
}

// 业务控制器继承后直接使用
[Log]
public class HomeController : BaseController
{
    public IActionResult Index()
    {
        // 无需额外赋值,直接调用属性即可
        var currentUserId = LogUserId;
        var currentPath = LogPath;
        return View();
    }
}

方案优势

  • 实现成本极低,无需调整依赖注入规则
  • HttpContext.Items是ASP.NET Core内置的单次请求临时存储,不会出现跨请求串值、线程安全问题
  • 无额外性能开销,除了控制器外,同请求的中间件、其他过滤器也能读取这两个参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:39:03