为AJAX加载PartialView,为非AJAX请求加载View
我想在Facebook上实现一些东西:
- 左键单击照片后,它通过AJAX加载
- 在中间点击滚动后,它会正常加载其他布局
现在我有了一个View,它以两种不同的方式加载到Controller中:
public ActionResult Overview() { return View("Overview"); } public ActionResult OverviewPartialView() { return PartialView("Overview"); }
在jquery脚本中它看起来像这样:
$(contentContainer).load(_link + 'PartialView');
我的问题是,有没有更好的方法来解决这个问题? 我在_ViewStart中尝试过类似的东西:
@{ Layout = "~/Views/Shared/_Layout.cshtml"; if (IsAjax) { Layout = null; } }
在Controller中有类似的东西:
public ActionResult Index() { if (Request.IsAjaxRequest()) return PartialView(); return View(); }
但是在那些解决方案中我遇到了缓存问题,在打开带有布局的页面之后,在AJAX请求中也加载了带有布局的页面。
您可以使用单个操作:
public ActionResult Overview() { return View(); }
在_ViewStart.cshtml
:
@{ Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/Layout.cshtml"; }
另一种可能性是使用以下内容:
public ActionResult Overview() { if (Request.IsAjaxRequest()) { return PartialView(); } return View(); }
那么如果你想避免缓存问题,你可以使用POST请求而不是GET:
$.post(_link, function(result) { $(contentContainer).html(result); });
或者在GET中使用$.ajax
并指定cache: false
,它将附加一个唯一的查询字符串参数以避免浏览器缓存:
$.ajax({ url: _link, type: 'GET', cache: false, success: function(result) { $(contentContainer).html(result); } });
您可以使用ActionFilter的半全局解决方案。 如果请求是AJAX(XHR),此示例将原始ViewResult转换为PartialViewResult
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class AjaxifyFilterAttribute : ActionFilterAttribute { public override void OnActionExecuted(ActionExecutedContext filterContext) { if(!filterContext.HttpContext.Request.IsAjaxRequest() || !(filterContext.Result is ViewResult)) return; var view = filterContext.Result as ViewResult; filterContext.Result = new PartialViewResult { TempData = view.TempData, ViewData = view.ViewData, ViewName = view.ViewName, ViewEngineCollection = view.ViewEngineCollection }; } }