ASP.NET MVC模态弹窗如何隐藏导航栏仅保留录入表单
ASP.NET MVC 模态框加载带导航栏完整页面的解决方案
核心原因:控制器默认返回的View()会自动套用全局母版页(包含导航栏、公共脚本引用等全站公共内容),AJAX请求弹窗内容时没有返回无布局的纯分部视图,同时前端逻辑存在参数传递、事件绑定的疏漏。
1. 修改控制器Edit方法,按请求类型返回对应内容
普通页面跳转访问Edit时返回带布局的完整页面,AJAX请求弹窗内容时返回无布局的纯表单分部视图;POST方法验证失败时也要对应返回分部视图,避免把完整页面塞回弹窗。
改完的控制器代码:
// GET: Products/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Product product = db.Products.Find(id); if (product == null) { return HttpNotFound(); } ViewBag.FK_CATEGORY = new SelectList(db.Categories, "CATEGORY_ID", "CATEGORY_NAME", product.FK_CATEGORY); // 判断为AJAX请求则返回无布局的分部视图 if (Request.IsAjaxRequest()) { // 第一个参数填写你自己编写的Edit分部视图的准确文件名即可 return PartialView("_EditProductModal", product); } return View(product); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "PRODUCT_ID,PRODUCT_NAME,FK_CATEGORY")] Product product) { if (ModelState.IsValid) { db.Entry(product).State = EntityState.Modified; db.SaveChanges(); // AJAX提交时返回成功状态标识,普通表单提交则跳转回列表页 if (Request.IsAjaxRequest()) { return Json(new { success = true }); } return RedirectToAction("Index"); } ViewBag.FK_CATEGORY = new SelectList(db.Categories, "CATEGORY_ID", "CATEGORY_NAME", product.FK_CATEGORY); // AJAX提交验证失败时返回分部视图,直接把验证错误展示在弹窗内 if (Request.IsAjaxRequest()) { return PartialView("_EditProductModal", product); } return View(product); }
注意:将你之前写的Edit分部视图重命名为
_EditProductModal.cshtml(分部视图推荐以下划线开头命名,也可以保留原文件名,只要和PartialView()方法中的参数名对应即可),放在~/Views/Products/目录下。
2. 修正Index页的模态框容器与JS逻辑
你当前的前端代码存在3个问题:
- 没有定义id为
myModalEdit的模态框容器 - JS逻辑没有传递当前编辑行的产品id参数
- Edit按钮的默认跳转行为没有阻止,点击时会同时触发页面跳转和AJAX请求
替换Index页相关代码为以下内容:
<!-- 编辑弹窗容器 --> <div class="modal fade" id="myModalEdit" role="dialog" tabindex="-1"> <div class="modal-dialog"> <div class="modal-content"> <!-- 分部视图内容会动态加载到此处 --> </div> </div> </div> <!-- 列表中的Edit按钮,将产品id存在data-id属性中,去掉href避免触发默认跳转 --> <a href="javascript:void(0)" class="btn btn-success edit-btn" data-id="@item.PRODUCT_ID"> Edit </a> | <script> // 页面加载完成后绑定编辑按钮点击事件,不使用行内onclick避免重复绑定问题 $(function(){ $('.edit-btn').click(function () { var productId = $(this).data('id'); // 拼接正确的Edit请求地址,携带id参数 var url = '@Url.Action("Edit", "Products")?id=' + productId; $.get(url, function (data) { $("#myModalEdit .modal-content").html(data); $("#myModalEdit").modal('show'); // 绑定弹窗内表单的AJAX提交事件,避免提交后页面跳转 $('#formsubmit').submit(function(e){ e.preventDefault(); $.post(url, $(this).serialize(), function(res){ if(res.success){ // 提交成功关闭弹窗,刷新列表数据 $('#myModalEdit').modal('hide'); location.reload(); }else{ // 验证失败时将带错误信息的表单替换到弹窗内 $("#myModalEdit .modal-content").html(res); } }); }); }); }); }) </script>
3. 补全Edit分部视图的结构
你当前的分部视图缺少Bootstrap模态框要求的外层结构和底部操作区,修改_EditProductModal.cshtml代码如下:
@model MyNewApp5.Models.Product <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Edit product</h4> </div> <!-- Modal body --> <div class="modal-body" id="editform"> <div class="form-horizontal"> @using (Html.BeginForm("Edit", "Products", FormMethod.Post, new { @id = "formsubmit" })) { @Html.AntiForgeryToken() @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.PRODUCT_ID) <div class="form-group"> @Html.LabelFor(model => model.PRODUCT_NAME, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.PRODUCT_NAME, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.PRODUCT_NAME, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.FK_CATEGORY, "FK_CATEGORY", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownList("FK_CATEGORY", null, htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.FK_CATEGORY, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <input type="submit" value="Save" class="btn btn-primary" /> </div> </div> } </div> </div>
修改完成后,AJAX请求拿到的就是纯表单内容,不会携带导航栏等母版页公共内容,弹窗加载正常,表单验证、保存逻辑也可以正常在弹窗内运行。
内容的提问来源于stack exchange,提问作者Tokhtar Aubakirov
相关产品推荐
相关产品推荐

