为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 }; } }