ASP.NET MVC控制器中向另一Action传递JSON数据失败如何解决?
ASP.NET MVC跨Action传递复杂对象解决方案
问题根源
window.location.href触发的是GET请求,Url.Action方法仅支持将简单类型参数序列化到URL查询字符串中,无法自动序列化Order这类自定义复杂对象,因此SeatSelection接口无法从GET请求参数中解析出order实例。
最优解决方案(无前端改动)
使用ASP.NET MVC内置的TempData完成跨Action数据传递,TempData默认存储在Session中,仅对后续的单次请求有效,完全适配当前重定向场景:
修改OrderData接口代码
[HttpPost] public ActionResult OrderData(Order order) { // 将order对象存入TempData TempData["SubmittedOrder"] = order; var result = new { redirectToUrl = Url.Action("SeatSelection", "Orders", new { id = order.ScreeningId }) }; return Json(result); }
修改SeatSelection接口代码
public ActionResult SeatSelection(int id) { // 从TempData中取出Order对象 var order = TempData["SubmittedOrder"] as Order; // 异常兜底逻辑 if (order == null) { return RedirectToAction("Index", "Home"); } var screeningInDb = _context.Screenings.Include(s => s.Seats).Single(s => s.Id == order.ScreeningId); var viewModel = new SeatSelectionViewModel { Seats = screeningInDb.Seats, NumberOfTicketsOrdered = order.NumberOfTicketsOrdered }; return View("SeatSelection", viewModel); }
备选方案
方案1:显式拼接查询参数
如果Order对象字段较少,可将所有字段显式传入Url.Action的路由参数中:
var result = new { redirectToUrl = Url.Action("SeatSelection", "Orders", new { id = order.ScreeningId, NumberOfTicketsOrdered = order.NumberOfTicketsOrdered, // 补充Order的所有其他字段 }) };
MVC模型绑定会自动将查询字符串中的字段组装为Order实例,缺点是字段过多时会导致URL超长,仅适合极简单的对象传递。
方案2:持久化存储后查询(生产环境推荐)
如果需要支持用户刷新SeatSelection页面,更稳妥的实现是:
- OrderData接口中将有效order对象存入数据库/分布式缓存,生成唯一orderId
- URL中仅传递orderId和screeningId
- SeatSelection接口中用orderId从数据库/缓存查询完整order对象
该方案不受Session过期、页面刷新影响,稳定性更高。
内容的提问来源于stack exchange,提问作者YarsCode
相关产品推荐
相关产品推荐

