跨布局页面共享局部视图时,如何在局部视图中使用"RenderBody()"?

How to use "RenderBody()" in partial view when the partial view is shared across layout pages?

以下是我的 ASP.NET MVC 应用程序中的确切场景:

有两个完全相同的布局页面。但是一个在“”标签中有 angular 相关属性,而另一个是非 angular 布局。为了避免在两个 razor 布局文件中重复标记,我想创建一个局部视图并在布局页面之间共享它。

以下是部分视图(剃刀),我将其命名为“_LayoutPartial”:

_LayoutPartial.cshtml

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            @Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
                <li>@Html.ActionLink("Home", "Index", "Home")</li>
                <li>@Html.ActionLink("About", "About", "Home")</li>
                <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
            </ul>
            @Html.Partial("_LoginPartial")
        </div>
    </div>
</div>
<div class="container body-content">
    @RenderBody()
    <hr />
    <footer>
        <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
    </footer>
</div>

以上部分观点在“_Layout.cshtml”和“_AngularLayout.cshtml”中分享如下:

_Layout.cshtml

<body>
    @Html.Partial("_LayoutPartial")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>

_AngularLayout.cshtml

<body ng-app="myAngularLab">
    @Html.Partial("_LayoutPartial")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
</body>

当我尝试 运行 MVC 应用程序时,出现以下错误:

The file "~/Views/Shared/_LayoutPartial.cshtml" cannot be requested directly because it calls the "RenderBody" method.

报错信息很明显,好像只能在母版页使用RenderBody方法,其他地方不行。但我很想知道我们如何通过编写通用代码而不是在两个布局页面中保留重复代码来拥有两个相同的布局页面(如示例所示略有不同)?

_Layout.cshtml:

试试这个
<body>
    @Html.Partial("_LayoutPartial")

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
   <div class="container body-content">
    @RenderBody()
    <hr />
    <footer>
        <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
    </footer>
</div>
</body>

并从 _LayoutPartial.cshtml 中删除 @RenderBody()

@RenderBody() 通常用于 布局页面 ,它呈现不在指定部分内的内容页面部分。

希望对您有所帮助:)

我认为您需要使用 "nested layout",将一个布局页面作为 "master page" 用于其他布局,类似于 webforms 对应物:

_BaseLayout.cshtml

<html>
<head>
    <!-- other header tags (link, meta, title etc.) -->

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")

    <!-- JS & CSS includes if available -->
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <!-- other elements -->
    </div>
    <div class="container body-content">
        @RenderBody()
        <!-- other elements -->
    </div>

    @RenderSection("scripts", required: false)
</body>
</html>

_Layout.cshtml

@{ Layout = "~/Views/Shared/_BaseLayout.cshtml"; } // put reference to base layout here

<div>
    <!-- Non-Angular layout -->
    @RenderBody()
</div>

_AngularLayout.cshtml

@{ Layout = "~/Views/Shared/_BaseLayout.cshtml"; } // put reference to base layout here

<div ng-app="myAngularLab">
    <!-- Angular layout -->
    @RenderBody()
</div>

使用"nested layout"的优势:

  1. 消除了重复 @Styles.Render@Scripts.Render 的需要,@RenderSection 也是如此(它们会自动插入到引用基本布局的每个页面中)。

  2. 无需使用多个 body 标签,只需替换为 div 标签即可查看页面内容。

无法直接请求文件"X",因为它调用了"RenderBody"方法肯定源自Html.Partial,直接从子布局调用, 其中 .

如果要为嵌套布局设置默认布局,请将子布局参考之一放入 _ViewStart.cshtml:

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

另一个注意事项:部分视图旨在用于视图页面,而不是布局页面。布局页面专门用作视图页面的占位符 - 不能通过操作方法直接访问。