一. 分部视图
对于 MVC 视图和 Razor Pages 页面, 都有分部视图功能. 通常将 MVC 视图和 Razor Pages 页面统称为 "标记文件", 下面会常提到该名词. 使用分部视图的优势包括:(1) 将大型标记文件分解为更小的组件.(2) 减少跨标记文件中, 常见标记内容的重复.
建议:(1)不应使用分部视图来维护常见布局元素, 常见布局元素应在 _Layout.cshtml 文件中指定, 比如页头, 页尾.(2)当需要呈现复杂逻辑或代码执行的应该使用视图组件.
1.1 声明分部视图
分部视图是在 Views 文件夹 (MVC) 或 Pages 文件夹 (Razor Pages) 中维护的 .cshtml 标记文件. 在 ASP.NET Core MVC 中, 控制器的 ViewResult 能够返回视图或分部视图. 在 ASP.NET Core 2.2 中 Razor Pages 的 PageModel 可以返回 PartialViewResult 分部视图.
分部视图不会运行 _ViewStart.cshtml 页, 这涉及到布局以后再讲. 分部视图的文件名通常以下划线 _ 开头, 没有. cshtml.cs 文件.
1.2 引用分部视图
在标记文件中, 有多种方法可引用分部视图. 建议应用程序使用以下异步呈现方法之一:(1) 分部标记帮助程序.(2) 异步 HTML 帮助程序. 不建议使用同步 HTML 帮助程序, 因为可能会出现死锁的情况, 同步方法以后版本中会删除, 这里不再介绍.
(1) 分部标记帮助程序
分部标记帮助程序会异步呈现内容, 并使用类似 HTML 的语法:
<partial name="_PartialName" />
当存在文件扩展名时, 标记帮助程序会引用分部视图, 该视图必须与调用分部视图的标记文件位于同一文件夹中:
<partial name="_PartialName.cshtml" />
以下示例从应用程序根目录引用分部视图. 以 (~/) 或 (/) 开头的路径, 指代应用程序根目录:
Razor 页面 CSHTML
- <partial name="~/Pages/Folder/_PartialName.cshtml" />
- <partial name="/Pages/Folder/_PartialName.cshtml" />
- MVC CSHTML
- <partial name="~/Views/Folder/_PartialName.cshtml" />
- <partial name="/Views/Folder/_PartialName.cshtml" />
使用相对路径的分部视图
<partial name="../Account/_PartialName.cshtml" />
(2) 异步 HTML 帮助程序
使用 HTML 帮助程序时, 最佳做法是使用 PartialAsync, 同步是使用 Partial(不建议使用同步).PartialAsync 返回包含在 Task<TResult> 中的 IHtmlContent 类型. 通过 @await 来引用该方法.
Razor 页面 CSHTML
- @await HTML.PartialAsync("~/Pages/Folder/_PartialName.cshtml")
- @await HTML.PartialAsync("/Pages/Folder/_PartialName.cshtml")
- mvc CSHTML
- @await HTML.PartialAsync("~/Views/Folder/_PartialName.cshtml")
- @await HTML.PartialAsync("/Views/Folder/_PartialName.cshtml")
也可以使用 RenderPartialAsync 呈现分部视图. 此方法不返回 IHtmlContent. 它将呈现的输出, 直接流式传输到响应, 因此在某些情况下它可提供更好的性能. 因为该方法不返回结果, 所以必须在 Razor 代码块内调用它:
- @{
- await HTML.RenderPartialAsync("_AuthorPartial");
- }
1.3 分部视图发现
如果按名称 (无文件扩展名) 引用分部视图, 则按所述顺序搜索以下位置:
(1) Razor 页面
1. 当前正在执行页面的文件夹
2. 该页面文件夹上方的目录图
- 3./Shared
- 4./Pages/Shared
- 5./Views/Shared
- (2) MVC
- 1./Areas/<Area-Name>/Views/<Controller-Name>
- 2./Areas/<Area-Name>/Views/Shared
- 3./Views/Shared
- 4./Pages/Shared
1.4 通过分部视图访问数据
实例化分部视图时, 它会获得父视图 (主视图) 的 ViewData 字典的副本. 在分部视图内, 对数据所做的更新不会保存到父视图中. 对分部视图中的 ViewData 更改, 会在分部视图返回时丢失.
以下示例演示如何将 ViewDataDictionary(ViewData 字典)的实例传递给分部视图:
@await HTML.PartialAsync("_PartialName", customViewData)
还可将模型 (实体对象) 传入分部视图. 模型可以是自定义对象.
@await HTML.PartialAsync("_PartialName", model)
二. 演示
下面演示一个 Razor 的分部视图(MVC 的参考官网示例). 示例中 Pages/ArticlesRP/ReadRP.cshtml 是主视图, Pages/Shared/_AuthorPartialRP.cshtml 是第一个分部视图, 传入 "作者".Pages/ArticlesRP/_ArticleSectionRP.cshtml 是第二个分部视图, 传入 ViewData 字典和 section 模型二个参数, 这二个参数是 PartialAsync 的方法重载. 三个文件结构如下:
(1) 创建实体类
- public class Article
- {
- public string Title { get; set; }
- public string AuthorName { get; set; }
- public string PublicationDate { get; set; }
- public List<ArticleSection> Sections { get; set; }
- }
- public class ArticleSection
- {
- public string Title { get; set; }
- public string Content { get; set; }
- }
(2)主视图
- public class ReadRPModel : PageModel
- {
- public Article Article { get; set; }
- public void OnGet()
- {
- Article = new Article()
- {
- Title = "来自 <共享分部视图文件路径> 的分部视图",
- AuthorName = "Abraham Lincoln",
- PublicationDate= "1863 年 11 月 19 日中午 12:00:00",
- Sections = new List<ArticleSection>() {
- new ArticleSection (){ Title="第一节索引", Content="八十七年前..." },
- new ArticleSection (){ Title="第二节索引", Content="如今, 我们正在进行一场伟大的内战, 考验着......" },
- new ArticleSection (){ Title="第三节索引", Content="然而, 从更广泛的意义上说, 我们无法奉献..." },
- }
- };
- }
- }
- @page
- @model ReadRPModel
- <h2>@Model.Article.Title</h2>
- @Model.Article.PublicationDate
@* 将作者名字传到 Pages\Shared\_AuthorPartialRP.cshtml*@
- <p>--------------------------------- 第一个分部视图 / Views/Shared/_AuthorPartial.cshtml</p>
- @await HTML.PartialAsync("../Shared/_AuthorPartialRP.cshtml", Model.Article.AuthorName)
- <p></p>
- @* Loop over the Sections and pass in a section and additional ViewData to
- the strongly typed Pages\ArticlesRP\_ArticleSectionRP.cshtml partial view. *@
- <p>--------------------------------- 第二个分部视图 / Views/Shared/_ArticleSection.cshtml</p>
- @{
- var index = 0;
- @foreach (var section in Model.Article.Sections)
- {
- @await HTML.PartialAsync("_ArticleSectionRP", section,
- new ViewDataDictionary(ViewData)
- {
- { "index", index }
- })
- index++;
- }
- }
(3) 分部视图 _AuthorPartialRP.cshtm
@* 将传过来的 string 类型映射 *@
- @model string
- <div>
- <h3>@Model</h3>
- </div>
(4) 分部视图 _ArticleSectionRP.cshtml
@using StudyRazorDemo.Models;
@* 将传过来的对象映射到 ArticleSection 中 *@
- @model ArticleSection
- <h3>@Model.Title Index: @ViewData["index"]</h3>
- <div>
- @Model.Content
- </div>
- <p></p>
启动程序, 运行 http://localhost:42921/ArticlesRP/ReadRP, 显示如下:
参考资料
ASP.NET Core 中的分部视图
来源: https://www.cnblogs.com/MrHSR/p/10525099.html