Ajax返回JSON中PartialView未生成编译HTML的问题排查
问题:Ajax调用后返回的PartialView HTML未正确渲染
我原本的Ajax调用后重新加载PartialView的代码运行正常,但为了增强错误处理修改代码后,返回的data.HTML不再是编译后的PartialView HTML内容,而是对象信息,请问哪里出错了?
原有正常运行的代码
后端C#代码:
public PartialViewResult AddPreferredPosition(string playerID, int positionID) { playerService.AddPlayerPreferredPosition(Guid.Parse(playerID), positionID); PreferredPositionsModel model = new PreferredPositionsModel(); model.PreferredPositions = playerService.GetPlayerPreferredPositions(Guid.Parse(playerID)); model.Positions = playerService.GetPositions(); return PartialView("~/Areas/Admin/Views/Player/Partials/PreferredPositions.cshtml", model); }
前端JavaScript代码:
var params = {}; params.playerID = $('#PlayerID').val(); params.positionID = $("select[name='ddlPositionID'] option:selected").val(); $.ajax({ type: 'POST', url: '/Admin/Player/AddPreferredPosition', data: params, success: function (data) { $('#PreferredPositions').html(data); } });
修改后的错误代码
后端C#代码:
public ActionResult AddPreferredPosition(string playerID, int positionID) { try { playerService.AddPlayerPreferredPosition(Guid.Parse(playerID), positionID); PreferredPositionsModel model = new PreferredPositionsModel(); model.PreferredPositions = playerService.GetPlayerPreferredPositions(Guid.Parse(playerID)); model.Positions = playerService.GetPositions(); return Json(new { Success = true, HTML = PartialView("~/Areas/Admin/Views/Player/Partials/PreferredPositions.cshtml", model) }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { return Json(new { Success = false, ErrorMessage = ex.Message, InnerException = (ex.InnerException != null ? ex.InnerException.Message : ""), ex.StackTrace }); } }
前端JavaScript代码:
$.ajax({ type: 'POST', url: '/Admin/Player/AddPreferredPosition', data: params, success: function (data) { if (data.Success) { $('#PreferredPositions').html(data.HTML); } else { alert(data.ErrorMessage); console.log(data.StackTrace); } } });
问题原因
你直接把PartialView()方法返回的PartialViewResult对象塞进了JSON里,这个对象本身并不是HTML字符串——它只是一个包含视图路径、模型等信息的操作结果对象。当ASP.NET序列化这个对象到JSON时,只会把它的公共属性序列化出来,而不会自动执行视图渲染生成HTML。
而原来的代码直接返回PartialViewResult时,ASP.NET的MVC框架会自动处理后续的视图渲染流程,最终返回编译好的HTML内容,这就是两者的核心区别。
解决方案
你需要手动把PartialViewResult渲染成HTML字符串,再将这个字符串放入JSON返回。可以在你的Controller里添加一个辅助方法来完成视图渲染:
private string RenderPartialViewToString(string viewName, object model) { // 设置视图模型 ViewData.Model = model; using (var stringWriter = new StringWriter()) { // 查找指定的PartialView var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); // 创建视图上下文 var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, stringWriter); // 渲染视图到StringWriter viewResult.View.Render(viewContext, stringWriter); // 释放视图资源 viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View); // 返回渲染后的HTML字符串 return stringWriter.GetStringBuilder().ToString(); } }
然后修改你的Action方法,使用这个辅助方法生成HTML:
public ActionResult AddPreferredPosition(string playerID, int positionID) { try { playerService.AddPlayerPreferredPosition(Guid.Parse(playerID), positionID); PreferredPositionsModel model = new PreferredPositionsModel(); model.PreferredPositions = playerService.GetPlayerPreferredPositions(Guid.Parse(playerID)); model.Positions = playerService.GetPositions(); // 调用辅助方法渲染PartialView为HTML字符串 string renderedHtml = RenderPartialViewToString("~/Areas/Admin/Views/Player/Partials/PreferredPositions.cshtml", model); return Json(new { Success = true, HTML = renderedHtml }, JsonRequestBehavior.AllowGet); } catch (Exception ex) { return Json(new { Success = false, ErrorMessage = ex.Message, InnerException = ex.InnerException?.Message ?? "", StackTrace = ex.StackTrace }, JsonRequestBehavior.AllowGet); } }
前端代码无需修改
你的前端代码逻辑是正确的,现在data.HTML会是渲染好的HTML字符串,直接插入到DOM中即可正常显示。
内容的提问来源于stack exchange,提问作者Mark Seymour
相关产品推荐
相关产品推荐

