首页 / ASP.NET Core / 正文

[ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的Layout布局(05)

4716 发布于: 2018-10-24 读完约需17分钟

什么是Layout ?

在现代的Web网站应用程序开发中,一个页面通常包含了几个部分(区域),如:头部,左侧导航,右侧主内容显示区域以及底部信息等等。在多页面开发过程中,除了右侧主内容显示区域的内容各不相同外,其他部分的内容都是相同的。这时,我们就需要使用Layout Page(布局页面)来装载相同的部分,不同的内容显示区域由每个页面自己根据实际情况渲即可。比如有如下的布局结构(图片来自微软ASP.NET Core文档):

ASP.NET Core Razor Pages页面布局结构示例

如果你对ASP.NET MVC熟悉,那么本文理解起来是非常容易的。因为Razor Pages中的布局页面和ASP.NET MVC中的布局页面相似。

在布局页面中,我们可以将通用的HTML结构代码(比如:CSS样式文件的引用,Javascript脚本文件的引用等)集中引用,这样可以有效地管理和维护通用的HTML代码,避免重复写同样的代码。假设不使用布局页面,如果有一天需要修改网站中所有页面的导航,我们得去修改每个页面的导航代码。但在使用了布局页面之后,就只需要修改布局页面中一处导航代码即可,大大方便了代码的维护。

官方约定,ASP.NET Core Razor Pages项目中的布局页面默认以_Layout.cshtml命名,并存放在项目的指定目录[/Pages/Shared/_Layout.cshtml]中,目录结构如下:

布局页面的目录位置

在一个Razor Pages应用程序中,可以不需要创建布局页面,也可以创建一个或者多个布局页面,只需要分别使用不同的布局页面文件名即可。

官方默认生成的布局页面_Layout.cshtml内容如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebApplication1</title>

    <environment names="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <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="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">WebApplication1</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
                @await Html.PartialAsync("_LoginPartial")
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2018 - WebApplication1</p>
        </footer>
    </div>

    <environment names="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment names="Staging,Production">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.6/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

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

一个简化版本的布局页面可能是这样的:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <link href="/css/site.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        @RenderBody()
    </body>
</html>

这个简化版的布局页面中只包含了@RenderBody()方法,其实这里的@RenderBody()你可以把它看成是一个占位符,当Razor内容页面引用这个_Layout.cshtml布局页面时,会将内容页面的内容填充到@RenderBody()的位置。

注意: 一个布局页面中只能同时包含一个@RenderBody()方法

如何引用Layout布局页面?

在Razor视图页面中,有一个叫Layout的属性,我们可以通过设置这个Layout属性来指定某个Razor视图页面需要使用的布局页面模板,如:

@{
    Layout = "_Layout";
}

其中,Layout的路径可以是完整的路径(如:~/Pages/Shared/_Layout.cshtml),也可以是以面示例的简写方式_Layout,如果使用简写的方式指定布局页面,那么Razor视图引擎将使用内置的视图搜索器搜索指定的布局文件。首先会搜索当前页面所在的目录,然后搜索Shared目录,搜索方式与部分视图的搜索方式是一致的。

Sections

在布局页面中,包含了@RenderBody()方法,但这个方法只能在页面文件中渲染一个位置,如果我们需要在页面文件中渲多个位置,是不是就不行了呢?

这时Sections就应该派上用场了。Sections对应的方法为:@RenderSection,在需要的地方使用如下方式标记:

@RenderSection("Scripts", required: false)

这里的RenderSection(...)有两个参数,第一个参数为占位名称,第二个参数表示是否是必须的,如果为true,那么在使用了这个布局页面的Razor内容页面中必须指定Scriptssection,如下:

@section Scripts {
     <script type="text/javascript" src="/scripts/main.js"></script>
   }

在某些情况下,我们还需要判断Razor页面是否指定了某个section,如果没有指定,则在_Layout中设置默认的内容,这时可以使用IsSectionDefined()方法,示例如下:

@if(IsSectionDefined("OptionalSection"))
{
    @RenderSection("OptionalSection")
}
else
{
    // 默认的内容
}

注意: IsSectionDefined()方法只能在布局页面中使用。

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

上一篇: [ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的Partial Views(部分视图)(04)

下一篇: [ASP.NET Web Api]在ASP.NET Web Api 2中如何返回不带双引号的纯文本字符串?

本文永久链接码友网 » [ASP.NET Core Razor Pages系列教程]ASP.NET Core Razor Pages中的Layout布局(05)

分享扩散:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册