HttpPost未跳转至View问题:模态框局部视图提交异常
问题描述
我有一个打开模态框编辑名称的按钮,代码如下:
<button type="button" data-toggle="modal" OnClick="showInPopup('@Url.Action("EditName", "ChangeRequest", new { Id = sf.Id }, Context.Request.Scheme)', 'Edit Name9')" data-target="#modalDiv" class="btn btn-sm btn-info"> <i class="fas fa-pencil-alt"></i> </button>
模态框代码:
<!-- Edit Folder Modal --> <div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Edit Name</h5> </div> <div class="modal-body" id="modalContent"> ... </div> </div> </div> </div>
打开模态框的AJAX脚本:
showInPopup = (url, title) => { $.ajax({ type: 'GET', url: url, success: function (res) { $('#editModal .modal-body').html(res); $('#editModal .modal-title').html(title); $('#editModal').modal('show'); // to make popup draggable //$('.modal-dialog').draggable({ // handle: ".modal-header" //}); } }) }
模态框内的局部视图代码:
@model RequestViewModel @{ Layout = null; } <div class="row"> <form asp-action="EditName" asp-route-id="@Model.SharedFile.Id" onsubmit="return jQueryAjaxPost(this);"> <fieldset> <div class="form-group py-3"> @Html.HiddenFor(x => x.SharedFile.Id) <h3>New Folder Name</h3> @* <label for="txtNewFoldName" class="form-label mt-4">New Folder Name</label> *@ @* <input asp-for="SharedFile.FileName" class="form-control" name="fileName"/> *@ <input class="form-control" id="=txtNewFoldName" name="fileOrFolderName" value="@Model.SharedFile.FileName"> </div> </fieldset> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Save changes</button> </div> </form> </div>
表单提交的AJAX脚本:
jQueryAjaxPost = form => { try { $.ajax({ type: 'POST', url: form.action, data: new FormData(form), contentType: false, processData: false, success: function (res) { if (res.isValid) { $('#editModal .modal-body').html(''); $('#editModal .modal-title').html(''); $('#editModal').modal('hide'); } else $('#form-modal .modal-body').html(res.html); }, error: function (err) { console.log(err) } }) //to prevent default form submit event return false; } catch (ex) { console.log(ex) } }
后端HttpPost控制器方法:
[HttpPost] public ActionResult EditName(int id, string fileOrFolderName, BaseViewModel bvm) { RequestViewModel rvm = ChangeRequest.SubmitEditFileOrFolderNameRequest(bvm.SharedFile, fileOrFolderName, User.Identity.Name, _memoryCache); rvm.SharedFile = DAL.GetFolderContents(id); return View("Confirmation", rvm); }
目前所有流程正常执行,POST方法能正确接收数据,控制器已执行到return View("Confirmation", rvm)断点,但页面并未跳转至确认页,尝试RedirectToAction也无效。而页面上非局部视图的按钮可以正常跳转至确认页,请问是否是模态框内的局部视图导致的问题?
问题原因
核心问题不是模态框或局部视图,而是表单提交使用了AJAX异步请求:
- 非模态框的按钮是普通表单提交(未通过AJAX拦截),浏览器会直接处理服务器返回的跳转或视图响应,因此能正常跳转。
- 模态框内的表单通过
jQueryAjaxPost函数用AJAX提交,AJAX默认会异步接收服务器返回的响应内容,不会自动触发页面跳转——哪怕控制器返回View或RedirectToAction,结果都会被传到AJAX的success回调里,而不是让浏览器加载新页面。
解决方案
根据需求选择以下方案之一:
方案1:AJAX成功后手动跳转(直接跳转到确认页)
修改控制器方法,返回确认页的URL,然后在AJAX回调中执行页面跳转:
控制器修改:
[HttpPost] public ActionResult EditName(int id, string fileOrFolderName, BaseViewModel bvm) { RequestViewModel rvm = ChangeRequest.SubmitEditFileOrFolderNameRequest(bvm.SharedFile, fileOrFolderName, User.Identity.Name, _memoryCache); rvm.SharedFile = DAL.GetFolderContents(id); // 返回JSON数据,包含跳转URL和验证状态 return Json(new { isValid = true, redirectUrl = Url.Action("Confirmation", "ChangeRequest", new { /* 传递确认页需要的参数 */ }) }); }
AJAX脚本修改:
jQueryAjaxPost = form => { try { $.ajax({ type: 'POST', url: form.action, data: new FormData(form), contentType: false, processData: false, success: function (res) { if (res.isValid) { $('#editModal').modal('hide'); // 手动跳转到确认页 window.location.href = res.redirectUrl; } else $('#editModal .modal-body').html(res.html); }, error: function (err) { console.log(err) } }) return false; } catch (ex) { console.log(ex) } }
方案2:在模态框中显示确认页内容
如果不需要跳转页面,而是在模态框内展示确认信息,可以保持控制器返回View("Confirmation", rvm),然后修改AJAX回调:
success: function (res) { if (res.isValid) { // 替换模态框内容为确认页 $('#editModal .modal-body').html(res); $('#editModal .modal-title').html('操作确认'); } else $('#editModal .modal-body').html(res.html); }
注意:确认页视图需要设置Layout = null;,避免加载完整布局。
方案3:放弃AJAX,使用普通表单提交
如果不需要异步提交的体验,可以移除onsubmit="return jQueryAjaxPost(this);",让表单以普通方式提交:
<form asp-action="EditName" asp-route-id="@Model.SharedFile.Id"> <!-- 表单内容不变 --> </form>
这种方式下,控制器返回View或RedirectToAction都会正常触发页面跳转,和非模态框的按钮行为一致。
内容的提问来源于stack exchange,提问作者Cory Battles
相关产品推荐
相关产品推荐

