如何将TempData转换为List<string>?传递列表遇空值问题求助
解决TempData传递List时转换为null的问题
看起来你遇到的核心问题是:TempData里明明有值,但跨请求读取时直接强制转换为List<string>却得到null。这是因为TempData的序列化机制导致的,下面是具体的解决方案和原因分析:
问题根源
在ASP.NET(包括MVC和Core)中,TempData跨请求传递对象时,会先把对象序列化后存储(默认存在Session或Cookie中):
- 传统ASP.NET MVC默认用
BinaryFormatter序列化,但跨请求后类型转换容易出现意外 - ASP.NET Core默认用
JsonSerializer把对象序列化为JSON字符串存储,此时TempData里实际存的是字符串,而非List<string>对象,直接用as List<string>自然会返回null
解决方案:序列化存储+反序列化读取
最稳妥的方式是手动把List<string>序列化为JSON字符串存储,读取时再反序列化回原类型。你可以选择两种常用的序列化工具:
方案1:使用Newtonsoft.Json(兼容性更好,推荐)
先确保项目安装了Newtonsoft.Json NuGet包。
修改存储TempData的代码(Experiment方法)
using Newtonsoft.Json; public ActionResult Experiment() { List<string> stringArray = new List<string>(); stringArray.Add("Experiment" + rn1.ToString()); stringArray.Add("Experiment" + rn2.ToString()); stringArray.Add("Experiment" + rn3.ToString()); var nextExperiment = stringArray.FirstOrDefault(); stringArray.RemoveAt(0); var experiment = new Experiment(); _context.Add(experiment); _context.SaveChanges(); // 将List序列化为JSON字符串存入TempData TempData["List"] = JsonConvert.SerializeObject(stringArray); return RedirectToAction(nextExperiment, new { id = experiment.EID }); }
修改读取TempData的代码(Experiment1方法)
using Newtonsoft.Json; [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Experiment1(ExperimentViewmodel experiment) { var newExperiment = new Experiment { Question1 = experiment.SelectedItem }; if (ModelState.IsValid) { _context.Update(newExperiment); await _context.SaveChangesAsync(); // 读取JSON字符串并反序列化为List<string> var jsonString = TempData["List"] as string; if (!string.IsNullOrEmpty(jsonString)) { var stringList = JsonConvert.DeserializeObject<List<string>>(jsonString); if (stringList != null && stringList.Any()) { var nextExperiment = stringList.FirstOrDefault(); stringList.RemoveAt(0); // 重新序列化剩余列表并存回TempData TempData["List"] = JsonConvert.SerializeObject(stringList); return RedirectToAction(nextExperiment, new { id = newExperiment.EID }); } } // 处理List为空或读取失败的兜底逻辑 return RedirectToAction("ExperimentComplete"); } return View(); }
方案2:使用ASP.NET Core内置的System.Text.Json
如果你的项目是ASP.NET Core 3.0+,可以直接用内置序列化工具,无需额外安装包:
存储代码修改
using System.Text.Json; // ... TempData["List"] = JsonSerializer.Serialize(stringArray); // ...
读取代码修改
using System.Text.Json; // ... var jsonString = TempData["List"] as string; if (!string.IsNullOrEmpty(jsonString)) { var stringList = JsonSerializer.Deserialize<List<string>>(jsonString); // 后续逻辑同方案1 } // ...
额外注意点
- 若用Cookie存储TempData(ASP.NET Core的
CookieTempDataProvider),要注意Cookie的4KB大小限制,如果列表元素过多,建议改用Session存储 - 每次修改列表后,务必重新序列化并存回TempData,保证后续请求能拿到最新的列表状态
内容的提问来源于stack exchange,提问作者gordana
相关产品推荐
相关产品推荐

