ASP.NET Core中Ajax弹窗新增记录残留更新数据问题
ASP.NET Core Ajax 新增/更新Category后弹窗残留旧数据问题解决
问题现象
在ASP.NET Core项目中使用Ajax实现Category的新增与更新功能,整体功能正常,但更新记录后弹窗关闭,再次点击新增记录时,弹窗未显示空表单,而是保留了上次更新的记录数据。
相关代码
前端表单视图
<form asp-action="AddOrEdit" asp-route-id="@Model.CategoryId" onsubmit="return jQueryAjaxPost(this);" autocomplete="off"> <input type="hidden" asp-for="CategoryId" /> <div class="form-group"> <label asp-for="CategoryId" class="control-label"></label> <input id="CategoryId" asp-for="CategoryId" class="form-control" /> </div> <div class="form-group"> <label asp-for="CategoryName" class="control-label"></label> <input id="CategoryName" asp-for="CategoryName" class="form-control"></input> </div> <div class="form-group submit-div"> <input id="SubmitForm" type="submit" value="حفظ" class="button-insert-model" /> </div> </form>
后端控制器代码
[HttpGet] [NoDirectAccess] public async Task<IActionResult> AddOrEdit(int id = 0) { if (id == 0) { return View(new Category()); } else { var cat = await _db.Categories.FindAsync(id); if (cat == null) { return NotFound(); } return View(cat); } } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> AddOrEdit(int id, [Bind("CategoryId, CategoryName")] Category category) { if (ModelState.IsValid) { if (id == 0) { _db.Add(category); await _db.SaveChangesAsync(); } else { try { _db.Update(category); await _db.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { // 可添加异常处理逻辑 } } return Json(new { isValid = true, html = Helper.RenderRazorViewToString(this, "_ViewAll", _db.Categories.ToList()) }); } return Json(new { isValid = false, html = Helper.RenderRazorViewToString(this, "AddOrEdit", category) }); }
页面列表与JS代码
<div class="insert-button-div"> <div class="container"> <div class="row"> <a onclick="showInPopup('@Url.Action("AddOrEdit","Home",null,Context.Request.Scheme)','Add Cat')">Add Cat</a> </div> </div> </div> <div class="table-div-grid text-center"> <div class="container"> <div class="row"> <table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model.CategoryId) </th> <th> @Html.DisplayNameFor(model => model.CategoryName) </th> <th></th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @item.CategoryName </td> <td class="td-operations"> <a onclick="showInPopup('@Url.Action("AddOrEdit","Home",new {id=item.CategoryId}, Context.Request.Scheme)','Edit Record')" class="button-edit-table">Edit</a> </td> </tr> } </tbody> </table> </div> </div> </div> <script> showInPopup = (url, title) => { $.ajax({ type: 'GET', url: url, success: function (res) { $('#form-modal .modal-body').html(res); $('#form-modal .modal-title').html(title); $('#form-modal').modal('show'); } }) } jQueryAjaxPost = form => { try { $.ajax({ type: 'POST', url: form.action, data: new FormData(form), contentType: false, processData: false, cache: false, success: function (res) { if (res.isValid) { $('#view-all').html(res.html) $('#form-modal .modal-body').html(''); $('#form-modal .modal-title').html(''); $('#form-modal').modal('hide'); } else $('#form-modal .modal-body').html(res.html); }, error: function (err) { console.log(err) } }) } catch (ex) { console.log(ex) } return false; } </script>
问题原因
- GET请求缓存:浏览器默认缓存GET请求结果,点击新增时可能直接返回之前编辑请求的缓存视图,而非后端生成的空表单。
- 弹窗DOM残留:仅在提交成功时清空模态框内容,手动关闭弹窗等场景下DOM内容未彻底清理,导致下次打开时残留旧数据。
- 表单重复绑定:表单中重复定义
CategoryId输入框(隐藏+可见),可能引发模型绑定残留值问题。
解决方案
1. 禁用GET请求缓存
修改showInPopup函数,添加cache: false参数强制浏览器不缓存GET请求:
showInPopup = (url, title) => { $.ajax({ type: 'GET', url: url, cache: false, // 禁用缓存 success: function (res) { $('#form-modal .modal-body').html(res); $('#form-modal .modal-title').html(title); $('#form-modal').modal('show'); } }) }
2. 监听弹窗隐藏事件,彻底清空DOM
添加模态框隐藏事件监听,确保每次关闭弹窗时都清空内容:
$('#form-modal').on('hidden.bs.modal', function () { $(this).find('.modal-body').empty(); $(this).find('.modal-title').empty(); });
3. 清理表单冗余元素
若无需用户手动编辑CategoryId,移除可见的CategoryId输入框,避免重复绑定:
<form asp-action="AddOrEdit" asp-route-id="@Model.CategoryId" onsubmit="return jQueryAjaxPost(this);" autocomplete="off"> <input type="hidden" asp-for="CategoryId" /> <div class="form-group"> <label asp-for="CategoryName" class="control-label"></label> <input id="CategoryName" asp-for="CategoryName" class="form-control"></input> </div> <div class="form-group submit-div"> <input id="SubmitForm" type="submit" value="حفظ" class="button-insert-model" /> </div> </form>
4. 后端添加响应头禁用缓存
在GET方法中添加响应头,强制浏览器不缓存视图:
[HttpGet] [NoDirectAccess] public async Task<IActionResult> AddOrEdit(int id = 0) { // 添加禁用缓存的响应头 Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate"; Response.Headers["Pragma"] = "no-cache"; Response.Headers["Expires"] = "0"; if (id == 0) { return View(new Category()); } else { var cat = await _db.Categories.FindAsync(id); if (cat == null) { return NotFound(); } return View(cat); } }
总结
通过禁用GET请求缓存、彻底清理弹窗DOM、优化表单结构和后端响应头设置,即可解决新增弹窗残留旧数据的问题,确保每次新增操作都获取到全新的空表单。
内容的提问来源于stack exchange,提问作者MuhammadElshater
相关产品推荐
相关产品推荐

