MVC 3: 当通过 ajax 加载时,如何呈现一个没有布局页面的视图?

我正在学习关于 渐进增强和我有一个关于 AJAXify 的观点的问题。在我的 MVC 3项目中,我有一个布局页面,一个视图开始页面和两个普通视图。

Viewstart 页面位于 View 文件夹的根目录中,因此适用于所有视图。它指定所有视图的布局页面都应该使用 _Layout.cshtml。布局页面包含两个导航链接,每个链接对应一个视图。这些链接使用 @Html.ActionLink()将自己呈现到页面。

现在我已经添加了 jQuery,希望劫持这些链接,并使用 Ajax 在页面上动态加载它们的内容。

<script type="text/javascript">
$(function () {
$('#theLink').click(function () {
$.ajax({
url: $(this).attr('href'),
type: "GET",
success: function (response) {
$('#mainContent').html(response);
}
});
return false;
});
});
</script>

我可以想到两种方法,但我都不是特别喜欢:

1)我可以把整个视图的内容放在一个局部视图中,然后让主视图在渲染时调用局部视图。这样,在控制器中使用 Request.IsAjaxRequest(),就可以根据请求是否是 Ajax 请求来返回 View()PartialView()。我不能将常规视图返回给 Ajax 请求,因为那样它将使用布局页面,并且我将获得注入的布局页面的第二个副本。但是,我不喜欢这样,因为它强迫我为标准 GET 请求创建只包含 @{Html.RenderPartial();}的空视图。

    public ActionResult Index()
{
if (Request.IsAjaxRequest())
return PartialView("partialView");
else
return View();
}

然后在 Index.cshtml 中执行以下操作:

@{Html.RenderPartial("partialView");}

2)当请求不是 Ajax 时,我可以从 _ viewstart 中移除布局指定并手动指定:

    public ActionResult Index()
{
if (Request.IsAjaxRequest())
return View(); // Return view with no master.
else
return View("Index", "_Layout"); // Return view with master.
}

有人有更好的建议吗?有没有办法返回没有布局页面的视图?如果它是一个 ajax 请求,那么明确地说“不要包含你的布局”要比明确地包含不是 ajax 的布局要容易得多。

162814 次浏览

~/Views/ViewStart.cshtml:

@{
Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}

在控制器里:

public ActionResult Index()
{
return View();
}

我更喜欢并且使用你的第一选择。我不喜欢 # 2,因为对我来说 View()意味着返回整个页面。一旦视图引擎使用完毕,它应该是一个完整的、有效的 HTML 页面。创建 PartialView()是为了返回任意的 HTML 块。

我不认为这是一个大问题,有一个看法,只是呼吁部分。它仍然是 DRY,允许您在两种情况下使用部分的逻辑。

许多人不喜欢用 Request.IsAjaxRequest()分割他们的动作调用路径,我能理解这一点。但是 IMO,如果你所做的只是决定是否调用 View()PartialView(),那么分支就不是一个大问题,并且易于维护(和测试)。如果您发现自己使用 IsAjaxRequest()来确定大部分操作如何执行,那么制作一个单独的 AJAX 操作可能更好。

您只需要创建两个布局:

  1. 空荡荡的布局

  2. 主要布局

然后在 _ viewStart 文件中编写下面的代码:

@{
if (Request.IsAjaxRequest())
{
Layout = "~/Areas/Dashboard/Views/Shared/_emptyLayout.cshtml";
}
else
{
Layout = "~/Areas/Dashboard/Views/Shared/_Layout.cshtml";
}
}

当然,也许这不是最好的解决方案

只要把下面的代码放在页面的顶部

@{
Layout = "";
}

对于 RubyonRails 应用程序,我可以通过指定 控制器操作中的 render layout: false,我想用 ajax html 来响应它。

您不必为此创建空视图。

在控制器中:

if (Request.IsAjaxRequest())
return PartialView();
else
return View();

返回 PartialViewResult 将在呈现响应时覆盖布局定义。

在 ASP.NET 5中,已经没有 Request 变量可用了。您现在可以使用 Context.Request 访问它

此外,现在已经没有 IsAjaxRequest ()方法了,你必须自己编写它,例如在扩展 httprequestextensions.cs 中

using System;
using Microsoft.AspNetCore.Http;


namespace Microsoft.AspNetCore.Mvc
{
public static class HttpRequestExtensions
{
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}


return (request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest");
}
}
}

我在这个问题上找了一段时间,希望对其他人也有所帮助;)

资料来源: https://github.com/aspnet/AspNetCore/issues/2729