布局通常包含常见的用户界面元素,例如应用头,导航或菜单元素和页脚,如图:
常见的HTML结构(例如脚本和样式表)也经常被应用程序中许多页面使用。所有这些共享元素都可以在布局中定义,然后由应用程序中使用的任何视图引用。布局减少了视图中代码的重复。
按照惯例,ASP.NET 应用程序的默认布局名为 _Layout.cshtml。 vs 项目模板在 Views/Shared 文件夹中包含此布局文件。
这个布局为应用程序中的视图定义了一个顶层模板。布局对应用程序来说不是必需的,应用程序可以定义多个布局,不同的视图指定不同的布局。
一个_Layout.cshtml 例子:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - MVCTest</title> <environment include="Development"> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" rel="external nofollow" /> <link rel="stylesheet" href="~/css/site.css" rel="external nofollow" /> </environment> <environment exclude="Development"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="external nofollow" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" rel="external nofollow" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" /> <link rel="stylesheet" href="~/css/site.min.css" rel="external nofollow" asp-append-version="true" /> </environment> </head> <body> <nav 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">MVCTest</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> </div> </div> </nav> <partial name="_CookieConsentPartial" /> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© 2019 - MVCTest</p> </footer> </div> <environment include="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 exclude="Development"> <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js" asp-fallback-src="~/lib/jquery/dist/jquery.min.js" asp-fallback-test="window.jQuery" crossorigin="anonymous" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT"> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/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" crossorigin="anonymous" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"> </script> <script src="~/js/site.min.js" asp-append-version="true"></script> </environment> @RenderSection("Scripts", required: false) </body> </html>
@RenderBody() 显示引用该布局的视图页面。
Razor 视图有一个 Layout 属性。单个视图通过设置此属性来指定布局:
@{ Layout = "_Layout"; }
指定布局也可以使用完整路径。当提供部分视图名称时,先搜索与控制器相关的文件夹,然后搜索共享文件夹。默认情况下,每个布局都必须调用 RenderBody() 方法。哪里调用 RenderBody() 方法,视图内容就在哪里渲染。
布局可以通过调用 RenderSection 方法,引用一个或多个部分。部分提供了组织某些页面元素放置位置的方法。每次调用 RenderSection 时,都可以指定该部分是必须还是可选。如果未找到必须的部分,将抛出异常。个别视图使用 @section Razor 语法指定要在某个部分中呈现的内容。如果视图定义了一个部分,那么它必须被渲染。
视图中的 @section 定义示例:
@section Scripts{ <script type="text/javascript" src="~/js/site.min.js"></script> }
在上面的代码中,验证脚本被添加到包含表单的视图的脚本部分。同一应用程序中其他视图可能不需要任何其他脚本,因此不需要定义脚本部分。
视图中定义的部分仅在其直接布局页面中可用。它们不能从局部视图,视图组件或视图系统的其他部分引用。
默认情况下,内容页面中的正文和所有部分都是必须由布局页面渲染。Razor 视图引擎通过跟踪主体和每个部分是否已渲染来实施此操作。
要想指示视图引擎忽略正文或部分,请在布局中调用 IgnoreBody 和 IgnoreSection 方法。
Razor 页面中的正文和每个部分必须呈现或忽略。
视图可以使用 Razor 指令做许多事情,例如导入命名空间或执行依赖注入。许多视图共享的指令可以在公共的 _ViewImports.cshtml 文件中指定。_ViewImports.cshtml 文件支持以下指令:
该文件不支持其他 Razor 特性,如函数和部分定义。
_ViewImports.cshtml 文件示例:
@using MVCTest @using MVCTest.Models @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper "MVCTest.TagHelpers.EmailTagHelper,MVCTest"
ASP.NET Core MVC 应用程序的 _ViewImports.cshtml 通常放在 Views 文件夹中。 _ViewImports.cshtml 文件可以放置在任何文件夹。在这种情况下,它将值应用于该文件夹及其子文件夹中的视图。 _ViewImports.cshtml 文件从根级开始处理,然后对每个文件夹处理,直到视图本身的位置。因此,在根级别指定的设置可能会在文件夹级别被覆盖。
如果为视图运行多个 _ViewImports.cshtml 文件,则 _ViewImports.cshtml 文件中包含的指令组合行为如下:
如果有代码需要在每个视图运行之前执行,这些代码应放在 _ViewStart.cshtml 文件中。_ViewStart.cshtml 文件位于 Views 文件夹中。 _ViewStart.cshtml 中列出的语句在每个完整视图(不包含布局和局部视图)之前运行。像 _ViewStart.cshtml 和 _ViewImports.cshtml 是层次结构。如果在控制器相关视图文件夹中定义了 _ViewStart.cshtml ,那么它将在 Views 文件夹根目录中定义的文件夹之后运行。
_ViewStart.cshtml 示例:
@{ Layout = "_Layout"; }
上面代码指定所有视图将使用 _Layout.cshtml 布局。