asp.net-core - 将对象(和子对象)从 Razor 页面发送到另一个页面
问题描述
我正在尝试将 ResumeInfo(Custom Object) 类型的对象从 razor 页面发送到另一个 razor 页面,它工作正常.....但我注意到该对象中的所有子对象都是空的,它们不应该是因为他们有价值观。
这是我从中创建对象的类,它有一个其他对象的列表(经验、语言、技能),当我将对象从一个 Razor 页面发送到另一个页面时,列表返回空,即使对象具有值,因为我在我将对象发送到另一个页面之前对其进行了测试。
public class ResumeInfo
{
public string FullName { get; set; }
public string Profession { get; set; }
public List<string> Socials { get; set; }
public List<Skill> Skills { get; set; }
public List<Language> Languages { get; set; }
public List<Experience> Experiences { get; set; }
public string AboutMe { get; set; }
public List<Language> GetLanguages()
{
if (Languages == null)
Languages = new List<Language>();
return Languages;
}
public List<Skill> GetSkills()
{
if (Skills == null)
Skills = new List<Skill>();
return Skills;
}
public List<Experience> GetExperiences()
{
if (Experiences == null)
Experiences = new List<Experience>();
return Experiences;
}
}
这就是我发送对象的方式:
public class ResumeFormModel : PageModel
{
[BindProperty]
public ResumeInfo Info { get; set; }
public IActionResult OnPost()
{
int counter = 0;
var socials = Request.Form["Socials"];
var languagesName = Request.Form["LanguagesName"];
var languageValue = Request.Form["LanguagesValue"];
var skillsName = Request.Form["SkillsName"];
var skillsValue = Request.Form["SkillsValue"];
var expTitle = Request.Form["ExperienceTitle"];
var expText = Request.Form["ExperienceText"];
foreach(string str in socials)
{
Info.Socials.Add(str);
Console.WriteLine(str);
}
counter = 0;
foreach(string str in languagesName)
Info.GetLanguages().Add(new Language(str, Int32.Parse(languageValue[counter++])));
counter = 0;
foreach (string str in skillsName)
Info.GetSkills().Add(new Skill(str, Int32.Parse(skillsValue[counter++])));
counter = 0;
foreach (string str in expTitle)
{
Info.GetExperiences().Add(new Experience(str, expText[counter++]));
Console.WriteLine(str);
}
return RedirectToPage("GenerateResume", Info);
}
}
请注意,来自 Object(ResumeInfo) 的其他属性,例如 (FullName, Profession, AboutMe) 工作正常并且它们具有值,它只是列表和子对象。
这就是我接收对象的方式。
public class GenerateResumeModel : PageModel
{
[BindProperty(SupportsGet = true)]
public ResumeInfo Info { get; set; }
public void OnGet()
{
//Console.WriteLine(Info.GetExperiences()[0].Name);
}
}
为什么不填充子对象?有没有其他方法可以发送对象?
解决方案
查看PageBase.RedirectToPage Method,我们可以看到 Object 是路由值。
在 Asp.net Core Razor 页面中,我们不能将复杂的对象作为路由数据传递。路线数据功能仅支持简单的对象,如int
和string
。如果要跨请求保留更复杂的对象,则需要使用Sessions
or TempData
(由会话状态支持)。
因此,您可以参考以下步骤来启用会话并在跨请求之间传输复杂对象。
在 Startup.cs 中启用会话中间件:调用
AddSession
inConfigureServices
,然后调用UseSession
inConfigure
。public void ConfigureServices(IServiceCollection services) { services.AddDistributedMemoryCache(); services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(10); //session expired time options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); services.AddRazorPages(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseAuthentication(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
添加 Session 或 TempData 扩展来存储对象。
//required //using Microsoft.AspNetCore.Http; //using Newtonsoft.Json; public static class SessionExtensions { public static void Set<T>(this ISession session, string key, T value) { session.SetString(key, JsonConvert.SerializeObject(value)); } public static T Get<T>(this ISession session, string key) { var value = session.GetString(key); return value == null ? default : JsonConvert.DeserializeObject<T>(value); } }
或者
//Required //using Microsoft.AspNetCore.Mvc.ViewFeatures; //using Newtonsoft.Json; public static class TempDataExtensions { public static void Set<T>(this ITempDataDictionary tempData, string key, T value) where T : class { tempData[key] = JsonConvert.SerializeObject(value); } public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class { object o; tempData.TryGetValue(key, out o); return o == null ? null : JsonConvert.DeserializeObject<T>((string)o); } }
使用 session 或 TempData 存储复杂对象:
ResumeForm Post 方法:
public IActionResult OnPost() { //set value for Info. ... //store value in session HttpContext.Session.Set<ResumeInfo>("Resume", Info); // use TempData store the object TempData.Set("Resume", Info); return RedirectToPage("GenerateResume", Info); }
然后,GenerateResume 页面 Get 方法中的代码:
public class GenerateResumeModel : PageModel { [BindProperty(SupportsGet = true)] public ResumeInfo Info { get; set; } public void OnGet() { var resume = HttpContext.Session.Get<ResumeInfo>("Resume"); var data = TempData.Get<ResumeInfo>("Resume"); //Console.WriteLine(Info.GetExperiences()[0].Name); } }
测试结果是这样的:
推荐阅读
- netlogo - 在将项目添加到列表之前更新使用孵化定义的项目的值
- python - 如何在 jinja 中同时循环遍历 2 个元素?
- javascript - 为什么这个 React 方法没有按预期工作?
- svg - 如何选择某个类的随机元素 | 绿袜 - GSAP
- java - 处理大量 POJO 的最佳方法
- ios - 如果对主纹理进行了 mipmap,是否需要对 multisample 纹理进行 mipmap?
- c++ - 尝试在 VS 中编写 C 代码,由于 C++ 错误而无法构建
- ios - iOS 应用程序在 iOS 12 或 13 中不占用整个屏幕
- javascript - 如何将javascript文件链接到id
- spring - java.lang.IllegalArgumentException:尝试使用空实体创建事件