.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();
关键调整说明
- 避免重复注册:原代码中同时调用
AddMvc()和AddControllers()会导致服务注册冲突,改用AddControllersWithViews()统一注册Controllers和Views组件,同时配置TempData提供器。 - 中间件顺序:
UseSession必须放在UseRouting之后、UseAuthorization之前,确保Session在路由匹配后、授权前初始化完成。 - 统一配置Json选项:将Json序列化配置移到全局
Configure<JsonOptions>,避免分散配置。
额外验证步骤
- 确认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设置。 - 模型序列化检查:确保
SomeModel类有公共无参构造函数,所有需要序列化的属性都是公共可访问的,避免反序列化失败。 - TempData用法确认:
TempData.Keep("SomeModel")在存入时已正确调用,确保数据不会被自动清除;读取后的TempData.Keep()也能保留数据供后续请求使用。
内容的提问来源于stack exchange,提问作者mizzppy
相关产品推荐
相关产品推荐

