为了保证网站整体风格的统一,以及避免页面元素的重复,asp.net core 提供布局视图 (layout view) 的机制。根据ASP.NET Core 中的布局 | Microsoft Docs的说明,下图是一张典型的页面布局:
(图片来源:ASP.NET Core 中的布局 | Microsoft Docs)。
变化的部分主要在 content 部分。那么,我们可先编写一个布局页面,该页面包括除 content 之外的其它页面元素,然后其它页面通过共享这些页面元素实现风格统一和避免重复代码的目的。按照约定,ASP.NET Core 应用的默认布局名为 _Layout.cshtml,一般放在 Views/Shared 文件夹下面。
创建布局页面作为母版页
在 Views 文件夹下新建 Shared 文件夹,然后选中 Shared 文件夹,从右键菜单中选择 Add ,选择 Razor Component:
在下一界面中选择 Razor Layout,使用默认的 _Layout.cshtml 作为文件名:
点击 Add 按钮,完成创建。visual studio IDE 已经提供了如下的起始代码:
其它页面如果共享 _Layout 的页面元素,则将页面本身的内容放在@RenderBody 位置。可以将 @RenderBody 理解为占位符。
Section
通过母版页,我们可以方便的共用一些页面内容,但是有些页面可能要重写母版页中一些内容,或者在母版页中插入自己想呈现的内容,而不是只能将子页面呈现在固定的位置。Razor 视图引擎提供了 Section 的概念,允许在子页面中定义 Section,母版视图中通过 RenderSection() 方式加载视图定义的 Section。当然,子页面中的 section 部分并不是每个页面都有,所以母版中必须有这种灵活性,不做强制性的要求。比如,假设一般情况下,页面中都有 footer 部分,但也可能有些页面没有,则我们可以在布局页中这样写:
简化页面
有了 RendorBody() 之后,其它页面相同的部分都可以拿掉。Razor 视图具有 Layout 属性。 单个视图通过设置 Layout 属性来指定布局:
@{
Layout = "_Layout";
}
如果某个视图不需要共享母版页,比如登录页面,则将 Layout 属性设置为 null:
@{
Layout = null;
}
如果每一个页面都需要这样引入,也挺费事的。所以 asp.net core 提供另外一个叫做 View Start 的 Razor 视图,在视图中统一声明 Layout 属性。其它页面默认情况下都按照 View Start 的声明导入母版视图。如果不需要导入,则在该页面中声明 Layout 属性为 null 即可。这样就大大降低了重复声明的代码,增加了灵活性。View Start 视图的文件名为 _ViewStart.cshtml。
以 details.cshtml 页面为例,之前的代码为:
@model StudentManagement.Models.Student
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.PageTitle</title>
</head>
<body>
<h3>@ViewBag.PageTitle</h3>
<div>
姓名: @Model.Name
</div>
<div>
专业: @Model.Major
</div>
</body>
</html>
精简后变为:
@model StudentManagement.Models.Student
<h3>@ViewBag.PageTitle</h3>
<div>
姓名: @Model.Name
</div>
<div>
专业: @Model.Major
</div>
源码
源码托管在 gitee,项目名称: aspnetcore-studentmanagement,为了记录完整的编写过程,重要步骤提交 tag 进行记录,本次代码 tag 为 v0.05。可以通过 git checkout v0.05 查看对应代码。
参考
ASP.NET Core 中的布局 | Microsoft Docs
ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门