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

控制器构造函数中Identity User值为null的解决方法

问题根因

ASP.NET MVC 生命周期中,控制器实例化发生在请求上下文绑定之前,此时Controller类的User属性还未被赋值,自然取到null。另外你当前代码保留了无参构造函数,Autofac解析时存在优先调用无参构造导致DbContext注入失败的隐患。
TrackerEnabledDbContext的ConfigureUsername方法接收的是Func<string>类型的延迟执行委托,只有实际写入审计日志时才会调用该委托获取用户名,根本不需要在控制器构造阶段就拿到用户值。

推荐解决方案(全局配置,无重复代码)

直接把用户名配置逻辑移到Autofac的DbContext注册阶段,委托从当前请求的HttpContext取用户信息即可,审计触发时请求上下文已经完全初始化,能正常拿到身份信息。

  1. 修改Global.asax中的Autofac注册代码:
builder.Register(c =>
{
    var context = new MyDbContext();
    // 配置延迟取值委托,审计记录生成时才会执行取值逻辑
    context.ConfigureUsername(() => 
        HttpContext.Current?.User?.Identity?.Name ?? "Anonymous"
    );
    return context;
}).AsSelf().InstancePerRequest();
  1. 清理控制器代码,删除无参构造和构造函数内的审计配置逻辑,避免重复代码和注入异常:
public class MyController : Controller
{
    private readonly MyDbContext db;

    public MyController(MyDbContext db)
    {        
        this.db = db;
    }

    // 后续业务Action逻辑保持不变
}

这种写法把审计配置全局收敛在注入层,后续不管是控制器、业务服务层、过滤器里用到MyDbContext,都会自动带审计配置,不需要每个地方重复写配置代码。

临时兼容方案(控制器内配置)

如果因为特殊场景必须在控制器内完成配置,就把配置逻辑从构造函数移到控制器的Initialize方法中,该方法执行时请求上下文已经绑定完成,User属性已赋值:

public class MyController : Controller
{
    private readonly MyDbContext db;

    public MyController(MyDbContext db)
    {        
        this.db = db;
    }

    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
        base.Initialize(requestContext);
        // 此处User属性已完成初始化,可正常取值
        db?.ConfigureUsername(() => User.Identity.Name);
    }
}

注意:该方案需要所有使用MyDbContext的控制器都重写Initialize方法,重复代码多,维护成本高,仅适合小项目临时使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:21:25