Session中序列化与反序列化IEnumerable报Json错误如何解决?
方案合理性说明
- 你当前的实现思路完全可行,通过Session序列化JSON存储筛选状态/结果,是Web项目实现分页、筛选状态保留的常见方案,没有本质缺陷。
错误原因
你出现反序列化异常的核心原因是存入Session的对象类型和读取时指定的反序列化目标类型不匹配:
- 存储时你传入的是
budget对象,类型为BudgetViewModel,序列化后生成的是单个JSON对象(你贴出的JSON内容开头为{也验证了这点) - 读取时你指定的反序列化目标类型是
IEnumerable<FBudget>,这是集合类型,要求输入的JSON必须是数组格式(开头为[),类型不匹配直接抛出序列化异常。
修复方案
根据你的实际需求选择对应修复方式即可:
方式1:存储筛选后的FBudget集合(适合数据量小、不需要实时更新的场景)
修改存储逻辑,将筛选后的查询结果存入Session,而非筛选条件对象:
// 先执行筛选得到结果集合 var filterExpression = BuildFilter(budget); var filteredRecords = _dbContext.FBudgets.Where(filterExpression).ToList(); // 存储集合到Session SessionExtension.SetObjectAsJson(HttpContext.Session, "SessionFilter", filteredRecords);
读取逻辑不需要修改,直接反序列化为IEnumerable<FBudget>即可正常使用。
方式2:存储筛选条件(适合数据量大、需要实时查询最新数据的场景)
修改读取逻辑,将存储的对象反序列化为和存入时一致的BudgetViewModel类型,再用该条件重新查询数据:
public IActionResult Index() { // 反序列化为存入时的BudgetViewModel类型 var savedFilter = SessionExtension.GetObjectFromJson<BudgetViewModel>(HttpContext.Session, "SessionFilter"); IEnumerable<FBudget> records = Enumerable.Empty<FBudget>(); if(savedFilter != null) { // 用保存的筛选条件重新查询最新数据 var filterExpression = BuildFilter(savedFilter); records = _dbContext.FBudgets.Where(filterExpression).ToList(); } var BudgetVM = new BudgetViewModel() { FBudget = new FBudget(), // 其他属性正常赋值 RecordsList = records }; return View(BudgetVM); }
额外优化建议
因为你的FBudget类包含导航属性(比如ItemMaster、Customer),序列化时可能出现循环引用问题,建议修改你的Session扩展方法,增加序列化配置避免报错:
public static void SetObjectAsJson(this ISession session, string key, object value) { session.SetString(key, JsonConvert.SerializeObject(value, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore })); }
内容的提问来源于stack exchange,提问作者chdev
相关产品推荐
相关产品推荐

