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

.NET Core 6中如何将HttpContext传入DbConnectionInterceptor获取用户信息

解决方案

核心问题修复

你遇到的编译错误是因为在配置AddDbContext阶段直接实例化EFConnectionInterceptor时,服务容器尚未构建完成,无法注入IHttpContextAccessor。正确的做法是将拦截器注册为服务,通过服务提供者延迟解析实例。

步骤1:注册拦截器为服务

在Program.cs中,先将EFConnectionInterceptor注册为Scoped服务(与IHttpContextAccessor的生命周期匹配):

builder.Services.AddHttpContextAccessor();
// 注册拦截器到服务容器
builder.Services.AddScoped<EFConnectionInterceptor>();

步骤2:通过服务提供者添加拦截器

修改AddDbContext的配置,使用AddInterceptors的重载方法,从服务容器中获取拦截器实例:

builder.Services.AddDbContext<MyContext>(options =>
    options
        .UseSqlServer(builder.Configuration.GetConnectionString("myconnstring"))
        // 延迟从服务容器解析拦截器
        .AddInterceptors(provider => provider.GetRequiredService<EFConnectionInterceptor>())
);

步骤3:优化拦截器代码(可选但推荐)

将同步执行的ExecuteNonQuery改为异步方法,避免阻塞线程,并确保调用基类方法:

public class EFConnectionInterceptor : DbConnectionInterceptor
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public EFConnectionInterceptor(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public override async Task ConnectionOpenedAsync(DbConnection connection, ConnectionEndEventData eventData, CancellationToken cancellationToken = default)
    {
        var username = _httpContextAccessor.HttpContext?.User?.Identity?.Name;
        if (!string.IsNullOrEmpty(username))
        {
            using var cmd = connection.CreateCommand();
            cmd.CommandText = "EXEC sp_set_session_context @key=N'Username', @value=@Username";
            
            var param = cmd.CreateParameter();
            param.ParameterName = "@Username";
            param.Value = username;
            cmd.Parameters.Add(param);

            await cmd.ExecuteNonQueryAsync(cancellationToken);
        }

        // 调用基类方法确保后续逻辑正常执行
        await base.ConnectionOpenedAsync(connection, eventData, cancellationToken);
    }
}

关键说明

  • 该方案无需修改DB First生成的MyContext,完全通过拦截器实现全局会话上下文设置。
  • 仅在HTTP请求上下文存在且用户已认证时,才会执行sp_set_session_context,兼容后台任务等非HTTP场景(此类场景下会跳过执行)。
  • 拦截器的Scoped生命周期确保每个请求都能获取到当前用户的身份信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:50:52