Razor页面传递自定义对象时子对象及集合为空该如何解决?
问题原因
RedirectToPage 方法传递对象时,会自动将对象的所有属性转换为扁平的查询字符串拼接在跳转URL后,仅支持string、int等基础简单类型的序列化。List<>集合、自定义类等复杂类型无法被正确序列化到查询字符串中,因此跳转后只有简单属性可以被模型绑定正常识别,集合、子对象属性自然为空。同时URL本身存在长度限制,即使手动拼接集合的查询参数,也很容易出现数据截断、绑定失败的问题。
可行的对象传递方式
使用TempData存储(最适合当前场景)
TempData默认基于会话实现,读取一次后会自动销毁,刚好匹配跨单次跳转传递数据的需求。使用时需要先将复杂对象序列化为JSON字符串存储,跳转后再反序列化:- 发送页面存数据:
// 引入System.Text.Json命名空间 TempData["ResumeInfo"] = JsonSerializer.Serialize(Info); return RedirectToPage("GenerateResume");- 接收页面取数据:
public void OnGet() { if (TempData.TryGetValue("ResumeInfo", out var infoJson)) { Info = JsonSerializer.Deserialize<ResumeInfo>(infoJson.ToString()); } }注意:
Skill、Language、Experience自定义类需要声明公共无参构造函数,否则反序列化会失败。使用Session存储
适合需要多次读取、数据要在会话内保留的场景,需要先在项目启动配置中开启Session服务:- Program.cs中添加配置:
builder.Services.AddSession(opt => { opt.IdleTimeout = TimeSpan.FromMinutes(30); opt.Cookie.HttpOnly = true; }); // 中间件配置要放在UseRouting之后、UseAuthorization之前 app.UseSession();- 发送页面存数据:
HttpContext.Session.SetString("ResumeInfo", JsonSerializer.Serialize(Info)); return RedirectToPage("GenerateResume");- 接收页面取数据:
public void OnGet() { var infoJson = HttpContext.Session.GetString("ResumeInfo"); if (!string.IsNullOrEmpty(infoJson)) { Info = JsonSerializer.Deserialize<ResumeInfo>(infoJson); // 用完可主动删除释放空间 HttpContext.Session.Remove("ResumeInfo"); } }直接渲染目标页面
不需要跳转,服务端直接返回目标页面的渲染结果,对象可以直接传递不会丢失,缺点是用户地址栏不会更新为目标页面地址,刷新页面会触发表单重复提交:// 替换原来的RedirectToPage return Page("GenerateResume", Info);临时数据库存储
适合数据重要、需要支持页面刷新不丢失的场景,先将ResumeInfo写入临时数据表,跳转时仅传递数据ID,目标页面用ID查询完整对象即可。
内容的提问来源于stack exchange,提问作者Kamel Yehya
相关产品推荐
相关产品推荐

