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

ASP.NET Core 7 MVC如何访问会话数据?.NET 4.8项目迁移遇阻

解决方案:.NET 7中跨类库访问会话状态

1. 正确配置IHttpContextAccessor与会话支持

在ASP.NET Core项目(Investo)的Program.cs中,按顺序完成以下配置:

var builder = WebApplication.CreateBuilder(args);

// 注册IHttpContextAccessor(官方默认Singleton,内部通过AsyncLocal安全持有请求上下文)
builder.Services.AddHttpContextAccessor();

// 启用会话服务,配置超时与Cookie属性
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

// 添加MVC服务
builder.Services.AddControllersWithViews();

// 注册General类库中需要访问会话的服务(必须是Scoped/Transient,禁止Singleton)
builder.Services.AddScoped<WebData>();

var app = builder.Build();

// 会话中间件必须放在UseRouting之后、UseEndpoints之前
app.UseSession();

app.UseRouting();
app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

2. 重构General类库中的会话访问逻辑

将原来依赖HttpContext.Current.Session的代码,改为通过构造函数注入IHttpContextAccessor来获取会话:

public class WebData
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    // 构造函数注入IHttpContextAccessor
    public WebData(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public string GetUserID()
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext?.Session == null)
        {
            throw new InvalidOperationException("会话未启用或无法访问请求上下文");
        }
        return httpContext.Session.GetString("UserID") ?? string.Empty;
    }
}

3. 在请求链路中使用类库服务

无论是Controller还是MapGet委托,都通过依赖注入获取WebData实例,避免手动new(否则注入不会生效):

示例1:Controller中使用

public class HomeController : Controller
{
    private readonly WebData _webData;

    public HomeController(WebData webData)
    {
        _webData = webData;
    }

    public IActionResult Index()
    {
        var userId = _webData.GetUserID();
        // 执行业务逻辑
        return View();
    }
}

示例2:MapGet委托中使用

app.MapGet("/api/user-id", (WebData webData) =>
{
    var userId = webData.GetUserID();
    return Results.Ok(new { UserId = userId });
});

关键注意事项

  • 禁止Singleton服务依赖IHttpContextAccessor:Singleton服务生命周期长于请求,会持有过期的HttpContext引用,导致随机报错或释放问题。必须使用Scoped/Transient注册需要访问会话的类库服务。
  • 会话中间件顺序不能错:app.UseSession()必须放在UseRouting之后、UseEndpoints之前,否则会话无法被正确初始化。
  • 避免手动实例化依赖注入类:所有使用WebData的地方必须通过DI容器获取实例,手动new WebData()会导致构造函数注入的IHttpContextAccessor为空。

内容的提问来源于stack exchange,提问作者Yisroel M. Olewski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:42:46