3

是否应该在操作中调用 PartialView() 使用布局?

这是我的行动:

public ActionResult SomeAction()
{
    if (Request.IsAjaxRequest())
        return PartialView();
    else
        return View();

}

这是我的 _ViewStart.cshtml:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

场景 #1:Action 调用未指定布局的视图。

@{
    //Layout = "~/Views/Shared/_SomeLayout.cshtml";
}
<h2>View!</h2>
  • 视图的结果:视图被包裹在一个布局中
  • PartialView 的结果:视图未包装在布局中

Darin Dimitrov的回应支持了这一点。

场景 #2:Action 调用指定布局的视图。

@{
    Layout = "~/Views/Shared/_SomeLayout.cshtml";
}
<h2>View!</h2>
  • 视图的结果:视图被包裹在一个布局中
  • PartialView 的结果:视图仍然包裹在布局中

Darin Dimitrov的其他回应似乎也支持了这一点。(注意:尽管他的回答是 AJAX 请求的全部内容,但这是对 OP 有两种观点的问题的回应,一种是完整的,一种是部分的。)

所以在第一个中,Darin 解释说如果你不想要布局,请使用 PartialView(),但在第二个中他说如果你不想要布局,那么这里有一个解决方法。

有人可以向我解释我是否缺少某些东西或为什么会这样。不管 Darin 怎么说,如果我只在 中设置布局_ViewStart.cshtml,那么我可以用 PartialView() 忽略它,但是如果我在 View 本身中设置另一个布局,那么我不能忽略它。

这有意义吗?我应该能够忽略这两种布局吗?如果不是,为什么?

4

1 回答 1

4

在 Razor 中,整页或部分页的渲染过程是相同的,因为它们使用相同的基类。对于整个页面和部分页面的渲染过程,都创建一个 RazorView 对象,但具有不同的构造函数参数。从源代码来看,这是呈现视图的两种方法。System.Web.Mvc 命名空间RazorViewEngine.cs

protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new RazorView(controllerContext, partialPath,
                                 layoutPath: null, runViewStartPages: false, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator)
        {
                DisplayModeProvider = DisplayModeProvider
        };
    }

protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var view = new RazorView(controllerContext, viewPath,
                                     layoutPath: masterPath, runViewStartPages: true, viewStartFileExtensions: FileExtensions, viewPageActivator: ViewPageActivator)
        {
                DisplayModeProvider = DisplayModeProvider
        };
        return view;
    }

layoutPath:null,runViewStartPages:false在构造函数参数中看到创建局部视图时。在您的场景 #1 中,这就是为什么 View 包含在布局中而不是 partialView 的原因。根据返回PartialView时的这些方法,ViewStart不会执行但返回View时会执行。

partialView 的默认布局为 null,就像在构造函数参数中指定的一样。但是在 ViewActionResult 返回后,可能已经指定了覆盖的布局。这就是您的场景 #2 中发生的情况。通过声明Layout = "~/Views/Shared/_SomeLayout.cshtml";您正在WebPageBase.Layout为某个路径指定属性,这将覆盖layoutPath:null. 即使您返回 PartialView() 剃须刀也会生成完整的视图。同样,如果您 Layout = null;在视图中声明,即使您从控制器 Razor 返回 View(),也会生成 partialView。因此,您的视图是部分视图还是完整视图,不取决于您是否返回View()PartialView()。这取决于 Layout 属性是 null 还是某个路径。因此,对于更具可读性的代码,当您想要生成 partialView 时,请使用return PartialView()并且不要在视图中定义任何 Layout。

于 2015-08-15T13:41:07.243 回答