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

.NET 6中Controller内TempData始终为空的问题排查

TempData通过Ajax存取始终为空的解决方案

核心问题定位

你的问题主要出在Program.cs中服务注册重复和中间件顺序不够严谨,同时需要确认Session的一致性是否正常。

修正后的Program.cs配置

首先简化服务注册逻辑,避免重复添加Mvc/Controllers组件,统一配置TempData提供器,并调整中间件顺序确保Session正确生效:

var builder = WebApplication.CreateBuilder(args);

// 注册Session依赖的分布式内存缓存
builder.Services.AddDistributedMemoryCache();

// 统一注册Controllers、Views和RazorPages,同时配置SessionStateTempDataProvider
builder.Services.AddControllersWithViews()
    .AddSessionStateTempDataProvider();
builder.Services.AddRazorPages();

// 配置Session参数
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromSeconds(10);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

// 全局配置Json序列化选项
builder.Services.Configure<JsonOptions>(opts => 
    opts.JsonSerializerOptions.PropertyNamingPolicy = null);

var app = builder.Build();

// 生产环境错误处理
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// UseSession必须放在UseRouting之后,UseAuthorization之前
app.UseSession();
app.UseAuthorization();

// 映射路由端点
app.MapRazorPages();
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Map}/{action=Index}/{id?}");

app.Run();

关键调整说明

  1. 避免重复注册:原代码中同时调用AddMvc()和AddControllers()会导致服务注册冲突,改用AddControllersWithViews()统一注册Controllers和Views组件,同时配置TempData提供器。
  2. 中间件顺序:UseSession必须放在UseRouting之后、UseAuthorization之前,确保Session在路由匹配后、授权前初始化完成。
  3. 统一配置Json选项:将Json序列化配置移到全局Configure<JsonOptions>,避免分散配置。

额外验证步骤

  1. 确认Session一致性:在两个Action中输出HttpContext.Session.Id,验证Ajax请求是否共享同一个Session:
    [HttpPost]
    public ActionResult TestSetTempData([FromBody] SomeModel theModel)
    {
        var sessionId = HttpContext.Session.Id;
        TempData["SomeModel"] = JsonSerializer.Serialize(theModel);
        TempData.Keep("SomeModel");
        return Json(new { SessionId = sessionId });
    }
    
    [HttpPost]
    public ActionResult TestGetTempData()
    {
        var sessionId = HttpContext.Session.Id;
        if (TempData["SomeModel"] != null)
        {
            var viewModel = JsonSerializer.Deserialize<SomeModel>(TempData["SomeModel"] as string);
            TempData.Keep();
            return Json(new { SessionId = sessionId, CallId = viewModel.CallId });
        }
        return Json(new { SessionId = sessionId, CallId = null });
    }
    
    前端控制台查看两次请求返回的SessionId是否一致,不一致则说明Session Cookie未正确携带,检查浏览器Cookie设置。
  2. 模型序列化检查:确保SomeModel类有公共无参构造函数,所有需要序列化的属性都是公共可访问的,避免反序列化失败。
  3. TempData用法确认:TempData.Keep("SomeModel")在存入时已正确调用,确保数据不会被自动清除;读取后的TempData.Keep()也能保留数据供后续请求使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:52:25