如何通过HTML按钮将List<T>从一个Controller传递到另一个Controller
如何将List从一个Controller传递到另一个Controller?
我在CalculationsController的POST方法CalculateMenu()中生成了一个List,目前已经通过StringBuilder生成HTML表格展示这个List,现在想添加一个按钮,点击后把这个List传递到另一个Controller(ReportController),试了两种方法都没成功:
CalculateMenu方法代码
[HttpPost] public async Task<IActionResult> CalculateMenu([FromForm] int[] peopleCount, [FromForm] DateOnly date) { StringBuilder resultString = new StringBuilder(); resultString.AppendLine("<style>table, th, td { table-layout: fixed; border: 1px solid; width: 100%; border-collapse: collapse; }</style>"); resultString.AppendLine("<h1>Answer:</h1>"); var resultIngredients = await _calculationsService.CalculateIngredients(peopleCount, date); resultString.Append(CalculateTotalWeightOfEveryIngredient(resultIngredients)); resultString.Append(await CalculatePrice(peopleCount, date)); //How to generate a button? What did i tried: //resultString.AppendLine($"<form method=\"what method should i use in this case?\" action=\"put here address of second controller(dont know how)\"> <button type=\"submit\"> submit </button> </form>"); return Content(resultString.ToString(), "text/html; charset=utf-8"); }
失败的两种尝试
- 尝试1:向CalculationsController的另一个方法发送POST请求再重定向,TempData未生效
[HttpPost] [Route("api/calculations/send")] public ActionResult Send() { TempData["mydata"] = "111"; return RedirectToAction("SaveReport", "ReportController"); } - 尝试2:将List序列化为JSON后通过查询字符串传递,查询字符串被截断
string serializedIngedientsList = JsonSerializer.Serialize(resultIngredients); resultString.AppendLine($"<button role=\"button\" class=\"sendBtn\"><a href=\"www.siteadress/api/reports/{serializedIngedientsList}\" style=\"text-decoration: none; color: #000000\"> Отчёт </a></button>");
可行的实现方案
方案1:修正TempData+重定向的用法
TempData默认依赖Session,需确保项目已配置Session支持。另外RedirectToAction的参数格式有误,目标Controller名称不需要加Controller后缀,且存储List时需先序列化:
- 在
CalculateMenu中生成带隐藏字段的表单:
// 在CalculateMenu方法末尾添加表单代码 var serializedIngredients = JsonSerializer.Serialize(resultIngredients); resultString.AppendLine($@" <form method=""post"" action=""/Calculations/Send""> <input type=""hidden"" name=""ingredientsJson"" value=""{serializedIngredients}""> <button type=""submit"">生成报告</button> </form>");
- 修改
Send方法:
[HttpPost] public ActionResult Send(string ingredientsJson) { // 序列化后存入TempData TempData["Ingredients"] = ingredientsJson; // 注意:Controller名称写"Report"而非"ReportController" return RedirectToAction("SaveReport", "Report"); }
- 在ReportController的
SaveReport中读取数据:
public IActionResult SaveReport() { if(TempData["Ingredients"] is string json) { var ingredients = JsonSerializer.Deserialize<List<YourIngredientType>>(json); // 执行报告保存逻辑 } return View(); }
方案2:直接通过表单POST到目标Controller
跳过中间方法,直接将List序列化后放入隐藏字段,表单action指向ReportController的SaveReport方法(需该方法支持POST请求):
- 在
CalculateMenu中生成表单:
var serializedIngredients = JsonSerializer.Serialize(resultIngredients); resultString.AppendLine($@" <form method=""post"" action=""/Report/SaveReport""> <input type=""hidden"" name=""ingredientsJson"" value=""{serializedIngredients}""> <button type=""submit"">生成报告</button> </form>");
- 在ReportController中实现方法:
[HttpPost] public IActionResult SaveReport(string ingredientsJson) { var ingredients = JsonSerializer.Deserialize<List<YourIngredientType>>(json); // 执行报告保存逻辑 return View(); }
方案3:使用Session存储数据
如果List数据量较大,Session是更稳定的选择,需先配置Session:
- 在Program.cs中添加Session配置:
builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(10); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; }); // 在app.UseRouting()之后添加 app.UseSession();
- 在
CalculateMenu中存储数据并生成按钮:
var serializedIngredients = JsonSerializer.Serialize(resultIngredients); HttpContext.Session.SetString("Ingredients", serializedIngredients); // 生成指向ReportController的表单 resultString.AppendLine(@" <form method=""get"" action=""/Report/SaveReport""> <button type=""submit"">生成报告</button> </form>");
- 在ReportController中读取数据:
public IActionResult SaveReport() { var json = HttpContext.Session.GetString("Ingredients"); if(!string.IsNullOrEmpty(json)) { var ingredients = JsonSerializer.Deserialize<List<YourIngredientType>>(json); // 执行报告保存逻辑 // 可选:用完后清除Session数据 HttpContext.Session.Remove("Ingredients"); } return View(); }
需要补充的信息
resultIngredients的具体类型(比如List<Ingredient>及Ingredient类的结构),这会影响序列化/反序列化的正确性- ReportController中
SaveReport方法的当前签名(是否接受参数、请求方法类型) - 项目是否已经配置了Session/TempData的支持(比如是否使用分布式缓存)
- List的数据量大小(若数据量极大,可能需要考虑数据库临时存储方案)
内容的提问来源于stack exchange,提问作者Nikita Khustochka
相关产品推荐
相关产品推荐

