MVC中Ajax调用HTTP Post后视图未更新为Post动作数据的问题
问题描述
默认显示单选框中ID为1的A1对应数据,选择A2单选框时,通过Ajax发起HTTP Post请求调用Index动作,但视图始终显示默认的A1数据,未更新为Post返回的新数据。已确认Ajax请求传递的Id=2成功绑定到控制器。
现有代码
单选框控件
<div class="form-check"> <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioA1" checked /> <label class="form-check-label" for="flexRadioDefaultA1"> A1</label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioA2" /> <label class="form-check-label" for="flexRadioDefaultA2"> A2</label> </div>
Ajax调用代码
<script type="text/javascript"> $(document).ready(function () { $('#flexRadioA1').click(function () { $.ajax({ type: "GET", url: '/RtCd/Index' }) }); $('#flexRadioA2').click(function () { $.ajax({ type: "POST", url: '/RtCd/Index', data: { Id: 2 } }) }); }); </script>
控制器代码
[HttpGet] public async Task<IActionResult> Index() { var uatContext = _context.RtCd.Include(r => r.Audit); var list = (from r in uatContext join u in _context.Util on r.UtilId equals u.UtilId where r.RtCd != "" && r.UtilId == 1 select new RtCdViewModel { RtCdId = r.RtCdId, RtCd = r.RtCd, UtilName = u.UtilName }); return View(await list.ToListAsync()); } [HttpPost] public async Task<IActionResult> Index(int Id) { var uatContext = _context.RtCd.Include(r => r.Audit); var list = (from r in uatContext join u in _context.Util on r.UtilId equals u.UtilId where r.RtCd != "" && r.UtilId == Id select new RtCdViewModel { RtCdId = r.RtCdId, RtCd = r.RtCd, UtilName = u.UtilName }); return View(await list.ToListAsync()); }
.csHtml视图代码
@model IEnumerable<MVCCode.ViewModel.RtCdViewModel> @{ ViewData["Title"] = "RT List"; } @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.RtcD) </td> <td> @Html.DisplayFor(modelItem => item.UtilName) </td> </tr> }
问题原因
- Ajax请求仅发送了请求,但未处理控制器返回的视图内容,没有将新数据对应的HTML替换到页面上。
- 视图中存在笔误:
item.RtcD应为item.RtCd,会导致数据显示异常。
解决方案
步骤1:修改视图,添加容器并修正笔误
给数据列表添加一个带ID的容器,方便后续替换内容,同时修正字段名:
@model IEnumerable<MVCCode.ViewModel.RtCdViewModel> @{ ViewData["Title"] = "RT List"; } <div id="rtCdListContainer"> <table> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.RtCd) <!-- 修正笔误 --> </td> <td> @Html.DisplayFor(modelItem => item.UtilName) </td> </tr> } </table> </div>
步骤2:修改Ajax代码,处理返回内容
添加success回调函数,将控制器返回的视图内容替换到页面容器中:
<script type="text/javascript"> $(document).ready(function () { $('#flexRadioA1').click(function () { $.ajax({ type: "GET", url: '/RtCd/Index', success: function(response) { // 提取返回视图中的容器内容并替换 $('#rtCdListContainer').html($(response).find('#rtCdListContainer').html()); } }) }); $('#flexRadioA2').click(function () { $.ajax({ type: "POST", url: '/RtCd/Index', data: { Id: 2 }, success: function(response) { $('#rtCdListContainer').html($(response).find('#rtCdListContainer').html()); } }); }); }); </script>
可选优化:使用局部视图提升性能
将数据列表部分抽成局部视图_RtCdList.cshtml:
@model IEnumerable<MVCCode.ViewModel.RtCdViewModel> <table> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.RtCd) </td> <td> @Html.DisplayFor(modelItem => item.UtilName) </td> </tr> } </table>
修改控制器,根据请求类型返回完整视图或局部视图:
[HttpGet] public async Task<IActionResult> Index() { var uatContext = _context.RtCd.Include(r => r.Audit); var list = (from r in uatContext join u in _context.Util on r.UtilId equals u.UtilId where r.RtCd != "" && r.UtilId == 1 select new RtCdViewModel { RtCdId = r.RtCdId, RtCd = r.RtCd, UtilName = u.UtilName }); // Ajax请求返回局部视图,否则返回完整视图 if (Request.Headers["X-Requested-With"] == "XMLHttpRequest") { return PartialView("_RtCdList", await list.ToListAsync()); } return View(await list.ToListAsync()); } [HttpPost] public async Task<IActionResult> Index(int Id) { var uatContext = _context.RtCd.Include(r => r.Audit); var list = (from r in uatContext join u in _context.Util on r.UtilId equals u.UtilId where r.RtCd != "" && r.UtilId == Id select new RtCdViewModel { RtCdId = r.RtCdId, RtCd = r.RtCd, UtilName = u.UtilName }); return PartialView("_RtCdList", await list.ToListAsync()); }
此时Ajax代码可简化为:
<script type="text/javascript"> $(document).ready(function () { $('#flexRadioA1').click(function () { $.ajax({ type: "GET", url: '/RtCd/Index', success: function(response) { $('#rtCdListContainer').html(response); } }) }); $('#flexRadioA2').click(function () { $.ajax({ type: "POST", url: '/RtCd/Index', data: { Id: 2 }, success: function(response) { $('#rtCdListContainer').html(response); } }); }); }); </script>
内容的提问来源于stack exchange,提问作者Sayeed Ahmed
相关产品推荐
相关产品推荐

