ASP.NET MVC同一模态框Upsert后无法编辑分类的问题
问题分析与修复方案
问题根源
- TempData的局限性:TempData仅在下一次请求中有效,而点击编辑按钮时,通过
data-bs-toggle直接触发模态框显示,浏览器并未重新加载整个Index页面,导致模态框始终展示首次渲染的「添加新分类」状态。 - 错误的跳转逻辑:点击编辑按钮调用
UpsertGET方法后,RedirectToAction("Index")会触发页面跳转,但Bootstrap模态框是客户端触发,跳转后的页面不会自动打开模态框,用户实际看到的还是旧页面的模态框内容。
修复步骤
1. 修改CategoryController的Upsert GET方法
将跳转逻辑改为返回模态框的局部视图,支持AJAX动态加载内容:
// GET: Upsert action to prepare the modal for edit or creation [HttpGet] public IActionResult Upsert(Guid? id) { Category category = new Category(); if (id.HasValue) { category = _unitOfWork.Category.Get(c => c.Id == id.Value); if (category == null) { return NotFound(); } } // 返回模态框局部视图,而非跳转页面 return PartialView("_CategoryModal", category); }
2. 创建局部视图_CategoryModal.cshtml
将原Index中的模态框内容抽成独立局部视图,直接绑定Category模型:
@model Category <div class="modal-content"> <form asp-controller="Category" asp-action="Upsert" method="post"> <div class="modal-header"> <h5 class="modal-title" id="categoryModalLabel"> @if (Model.Id != Guid.Empty) { <span>Edit Category</span> } else { <span>Add New Category</span> } </h5> <button type="button" style="box-shadow: none" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <!-- Hidden Field for Id --> <input type="hidden" id="Id" name="Id" value="@Model.Id" /> <div class="mb-3"> <label for="CategoryName" class="form-label fw-bold ms-1">Category Name</label> <input type="text" class="form-control" id="CategoryName" name="CategoryName" value="@Model.CategoryName" required placeholder="Category Name" /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Dismiss</button> <button type="submit" class="btn btn-success">Save</button> </div> </form> </div>
3. 修改Index.cshtml的模态框与按钮逻辑
保留模态框外壳,通过AJAX动态填充内容,替换原有的直接触发逻辑:
@model IEnumerable<Category> <div class="container mt-4"> <div class="card"> <div class="card-header d-flex justify-content-between align-items-center"> <h5 class="mb-0">Categories Data</h5> <button class="btn btn-primary" style="box-shadow: none" id="btnAddCategory"> <i class="fas fa-plus-circle"></i> Add Category </button> <!-- 模态框外壳,内容通过AJAX动态加载 --> <div class="modal fade" id="categoryModal" tabindex="-1" aria-labelledby="categoryModalLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div id="modalContent"></div> </div> </div> </div> <div class="card-body"> <table class="table table-bordered"> <thead class="thead-light"> <tr> <th>S/N</th> <th>Category Name</th> <th>Created At</th> <th>Action</th> </tr> </thead> <tbody> @{ int index = 1; } @foreach (var category in Model) { <tr> <td>@index</td> <td>@category.CategoryName</td> <td>@category.CreatedAt.ToString("yyyy-MM-dd")</td> <td> <button class="btn btn-secondary btnEditCategory" data-id="@category.Id">Edit</button> </td> </tr> index++; } </tbody> </table> </div> </div> </div> <!-- AJAX脚本,处理模态框加载逻辑 --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> // 添加新分类按钮事件 $("#btnAddCategory").click(function () { $.get("/Category/Upsert", function (data) { $("#modalContent").html(data); $("#categoryModal").modal("show"); }); }); // 编辑按钮事件 $(".btnEditCategory").click(function () { var id = $(this).data("id"); $.get(`/Category/Upsert?id=${id}`, function (data) { $("#modalContent").html(data); $("#categoryModal").modal("show"); }); }); </script>
4. 完善Upsert POST方法(若未实现)
确保保存逻辑完成后重定向回Index页面:
[HttpPost] public IActionResult Upsert(Category category) { if (ModelState.IsValid) { if (category.Id == Guid.Empty) { // 创建新分类 category.CreatedAt = DateTime.Now; _unitOfWork.Category.Add(category); } else { // 更新现有分类 _unitOfWork.Category.Update(category); } _unitOfWork.Save(); return RedirectToAction("Index"); } // 验证失败时返回局部视图,保留用户输入 return PartialView("_CategoryModal", category); }
内容的提问来源于stack exchange,提问作者Maruf Hasnat
相关产品推荐
相关产品推荐

