如何成功将Ajax POST的列表数据从MVC Action传递至另一Action?
问题解决:Ajax POST数据后RedirectToAction列表数据丢失
问题原因
- RedirectToAction的本质:它会返回302重定向响应,浏览器会发起全新的GET请求。直接把列表对象作为路由参数传递时,MVC路由系统无法将复杂的列表对象序列化为URL参数,导致GET Action接收的参数为null。
- Ajax异步特性:Ajax请求是异步的,即使控制器返回重定向,前端也不会自动跳转页面——Ajax默认只处理响应内容,不会触发浏览器的跳转行为。
解决方案
方案1:用TempData临时存储数据(推荐)
TempData适合临时跨Action传递数据,存储的数据仅在下次请求有效,适配重定向场景。
修改控制器代码:
using Newtonsoft.Json; // 需要引用Newtonsoft.Json NuGet包,或替换为System.Text.Json [HttpPost] public IActionResult CreateOrderWithButtonCheckedProducts(List<ProductViewModel> productViewModel) { // 将列表序列化为JSON存入TempData TempData["ProductList"] = JsonConvert.SerializeObject(productViewModel); return RedirectToAction("CreateOrderWithButtonCheckedProduct", "Order"); } [HttpGet] public IActionResult CreateOrderWithButtonCheckedProduct() { var productList = new List<ProductViewModel>(); // 从TempData取出并反序列化为列表 if (TempData["ProductList"] != null) { productList = JsonConvert.DeserializeObject<List<ProductViewModel>>(TempData["ProductList"].ToString()); } // 将数据传给视图 return View(productList); }
方案2:POST Action直接返回视图(跳过重定向)
如果不需要通过GET请求展示页面,可以直接在POST Action中返回目标视图,把数据直接传给视图:
修改控制器代码:
[HttpPost] public IActionResult CreateOrderWithButtonCheckedProducts(List<ProductViewModel> productViewModel) { // 可在此处添加业务逻辑处理 // 直接返回目标视图并传入数据 return View("CreateOrderWithButtonCheckedProduct", productViewModel); }
同时调整前端Ajax的成功回调(如果需要更新页面):
success: function (result) { // 用返回的视图HTML替换当前页面内容 $("body").html(result); }
方案3:替换Ajax为表单提交(适合需要浏览器跳转的场景)
如果希望保持浏览器跳转的行为,可以放弃Ajax,动态生成表单提交数据:
修改前端代码:
$("#BtnCreateOrderLast").click(function () { var form = $('<form>', { method: 'POST', action: '/Order/CreateOrderWithButtonCheckedProducts' }); $("#tblDemo tbody tr").each(function (index) { var currentRow = $(this); if (currentRow.find(".ChangeWidthF").is(":checked")) { // 按MVC模型绑定规则生成隐藏字段 form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].ProductName`, value: currentRow.find("td:eq(0)").html() })); form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].ProductCode`, value: currentRow.find("td:eq(1)").html() })); form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].Cost`, value: currentRow.find("td:eq(2)").html() })); form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].Stock`, value: currentRow.find("td:eq(3)").text() })); form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].Konsinye`, value: currentRow.find("td:eq(4)").html() })); form.append($('<input>', { type: 'hidden', name: `ProductViewModel[${index}].CountOfProduct`, value: currentRow.find("td:eq(5) input").val() })); } }); // 提交表单 form.appendTo('body').submit(); });
控制器代码同方案1,用TempData存储数据后重定向。
内容的提问来源于stack exchange,提问作者Osman TÜRK
相关产品推荐
相关产品推荐

