为AJAX加载PartialView,为非AJAX请求加载View

时间:2011-07-03 12:20:02

标签: jquery ajax asp.net-mvc-3 razor

我想在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请求中也加载了带布局的页面。

2 个答案:

答案 0 :(得分:10)

您可以使用单一操作:

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

答案 1 :(得分:2)

您可以将半全局解决方案与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
        };
    }
}