You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

问题原因

  1. GET请求缓存:浏览器默认缓存GET请求结果,点击新增时可能直接返回之前编辑请求的缓存视图,而非后端生成的空表单。
  2. 弹窗DOM残留:仅在提交成功时清空模态框内容,手动关闭弹窗等场景下DOM内容未彻底清理,导致下次打开时残留旧数据。
  3. 表单重复绑定:表单中重复定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:24:54