ASP.NET Core 中的分部视图Partial views in ASP.NET Core

作者:Steve SmithLuke LathamMaher JENDOUBIRick AndersonScott SauberBy Steve Smith, Luke Latham, Maher JENDOUBI, Rick Anderson, and Scott Sauber

分部视图是 Razor 标记文件 (.cshtml ),它在另一个标记文件呈现的输出中呈现 HTML 输出 。A partial view is a Razor markup file (.cshtml) that renders HTML output within another markup file's rendered output.

在开发 MVC 应用程序(其中标记文件称为“视图” )或 Razor Pages 应用程序(其中标记文件称为“页”)时,均会使用术语 “分部视图” 。The term partial view is used when developing either an MVC app, where markup files are called views, or a Razor Pages app, where markup files are called pages. 本主题通常将 MVC 视图和 Razor Pages 页面称为“标记文件” 。This topic generically refers to MVC views and Razor Pages pages as markup files.

查看或下载示例代码如何下载View or download sample code (how to download)

何时使用分部视图When to use partial views

分部视图是执行下列操作的有效方式:Partial views are an effective way to:

  • 将大型标记文件分解为更小的组件。Break up large markup files into smaller components.

    在由多个逻辑部分组成的大型复杂标记文件中,在分部视图中处理隔开的每个部分是有利的。In a large, complex markup file composed of several logical pieces, there's an advantage to working with each piece isolated into a partial view. 标记文件中的代码是可管理的,因为标记仅包含整体页面结构和对分部视图的引用。The code in the markup file is manageable because the markup only contains the overall page structure and references to partial views.

  • 减少跨标记文件中常见标记内容的重复。Reduce the duplication of common markup content across markup files.

    当在标记文件中使用相同的标记元素时,分部视图会将重复的标记内容移到一个分部视图文件中。When the same markup elements are used across markup files, a partial view removes the duplication of markup content into one partial view file. 在分部视图中更改标记后,它会更新使用该分部视图的标记文件呈现的输出。When the markup is changed in the partial view, it updates the rendered output of the markup files that use the partial view.

不应使用分部视图来维护常见布局元素。Partial views shouldn't be used to maintain common layout elements. 常见布局元素应在 _Layout.cshtml 文件中指定。Common layout elements should be specified in _Layout.cshtml files.

请勿使用需要复杂呈现逻辑或代码执行来呈现标记的分部视图。Don't use a partial view where complex rendering logic or code execution is required to render the markup. 使用视图组件而不是分部视图。Instead of a partial view, use a view component.

声明分部视图Declare partial views

分部视图是在 Views 文件夹 (MVC) 或 Pages 文件夹 (Razor Pages) 中维护的 .cshtml 标记文件。A partial view is a .cshtml markup file maintained within the Views folder (MVC) or Pages folder (Razor Pages).

在 ASP.NET Core MVC 中,控制器的 ViewResult 能够返回视图或分部视图。In ASP.NET Core MVC, a controller's ViewResult is capable of returning either a view or a partial view. 在 Razor Pages 中,PageModel 可以返回表示为 PartialViewResult 对象的分部视图。In Razor Pages, a PageModel can return a partial view represented as a PartialViewResult object. 引用分部视图部分介绍了引用和呈现分部视图。Referencing and rendering partial views is described in the Reference a partial view section.

与 MVC 视图或页面呈现不同,分部视图不会运行 _ViewStart.cshtml 。Unlike MVC view or page rendering, a partial view doesn't run _ViewStart.cshtml. 有关 _ViewStart.cshtml 的详细信息,请参阅 ASP.NET Core 中的布局For more information on _ViewStart.cshtml, see ASP.NET Core 中的布局.

分部视图的文件名通常以下划线 (_) 开头。Partial view file names often begin with an underscore (_). 虽然未强制要求遵从此命名约定,但它有助于直观地将分部视图与视图和页面区分开来。This naming convention isn't required, but it helps to visually differentiate partial views from views and pages.

分部视图是在 Views 文件夹中维护的 .cshtml 标记文件。A partial view is a .cshtml markup file maintained within the Views folder.

控制器的 ViewResult 能够返回视图或分部视图。A controller's ViewResult is capable of returning either a view or a partial view. 引用分部视图部分介绍了引用和呈现分部视图。Referencing and rendering partial views is described in the Reference a partial view section.

与 MVC 视图呈现不同,分部视图不会运行 _ViewStart.cshtml 。Unlike MVC view rendering, a partial view doesn't run _ViewStart.cshtml. 有关 _ViewStart.cshtml 的详细信息,请参阅 ASP.NET Core 中的布局For more information on _ViewStart.cshtml, see ASP.NET Core 中的布局.

分部视图的文件名通常以下划线 (_) 开头。Partial view file names often begin with an underscore (_). 虽然未强制要求遵从此命名约定,但它有助于直观地将分部视图与视图区分开来。This naming convention isn't required, but it helps to visually differentiate partial views from views.

引用分部视图Reference a partial view

在 Razor Pages PageModel 中使用分部视图Use a partial view in a Razor Pages PageModel

在 ASP.NET Core 2.0 或 2.1 中,以下处理程序方法将 _AuthorPartialRP.cshtml 分部视图呈现给响应 :In ASP.NET Core 2.0 or 2.1, the following handler method renders the _AuthorPartialRP.cshtml partial view to the response:

public IActionResult OnGetPartial() =>
    new PartialViewResult
    {
        ViewName = "_AuthorPartialRP",
        ViewData = ViewData,
    };

在 ASP.NET Core 2.2 或更高版本中,处理程序方法也可以调用 Partial 方法来生成 PartialViewResult 对象:In ASP.NET Core 2.2 or later, a handler method can alternatively call the Partial method to produce a PartialViewResult object:

public IActionResult OnGetPartial() =>
    Partial("_AuthorPartialRP");

在标记文件中使用分部视图Use a partial view in a markup file

在标记文件中,有多种方法可引用分部视图。Within a markup file, there are several ways to reference a partial view. 我们建议应用程序使用以下异步呈现方法之一:We recommend that apps use one of the following asynchronous rendering approaches:

在标记文件中,有两种方法可引用分部视图:Within a markup file, there are two ways to reference a partial view:

我们建议应用程序使用异步 HTML 帮助程序We recommend that apps use the Asynchronous HTML Helper.

分部标记帮助程序Partial Tag Helper

分部标记帮助程序要求 ASP.NET Core 2.1 或更高版本。The Partial Tag Helper requires ASP.NET Core 2.1 or later.

分部标记帮助程序会异步呈现内容并使用类似 HTML 的语法:The Partial Tag Helper renders content asynchronously and uses an HTML-like syntax:

<partial name="_PartialName" />

当存在文件扩展名时,标记帮助程序会引用分部视图,该视图必须与调用分部视图的标记文件位于同一文件夹中:When a file extension is present, the Tag Helper references a partial view that must be in the same folder as the markup file calling the partial view:

<partial name="_PartialName.cshtml" />

以下示例从应用程序根目录引用分部视图。The following example references a partial view from the app root. 以波形符斜杠 (~/) 或斜杠 (/) 开头的路径指代应用程序根目录:Paths that start with a tilde-slash (~/) or a slash (/) refer to the app root:

Razor 页面Razor Pages

<partial name="~/Pages/Folder/_PartialName.cshtml" />
<partial name="/Pages/Folder/_PartialName.cshtml" />

MVCMVC

<partial name="~/Views/Folder/_PartialName.cshtml" />
<partial name="/Views/Folder/_PartialName.cshtml" />

以下示例引用使用相对路径的分部视图:The following example references a partial view with a relative path:

<partial name="../Account/_PartialName.cshtml" />

有关更多信息,请参见ASP.NET Core 中的部分标记帮助程序For more information, see ASP.NET Core 中的部分标记帮助程序.

异步 HTML 帮助程序Asynchronous HTML Helper

使用 HTML 帮助程序时,最佳做法是使用 PartialAsyncWhen using an HTML Helper, the best practice is to use PartialAsync. PartialAsync 返回包含在 Task<TResult> 中的 IHtmlContent 类型。PartialAsync returns an IHtmlContent type wrapped in a Task<TResult>. 通过在等待的调用前添加 @ 字符前缀来引用该方法:The method is referenced by prefixing the awaited call with an @ character:

@await Html.PartialAsync("_PartialName")

当存在文件扩展名时,HTML 帮助程序会引用分部视图,该视图必须与调用分部视图的标记文件位于同一文件夹中:When the file extension is present, the HTML Helper references a partial view that must be in the same folder as the markup file calling the partial view:

@await Html.PartialAsync("_PartialName.cshtml")

以下示例从应用程序根目录引用分部视图。The following example references a partial view from the app root. 以波形符斜杠 (~/) 或斜杠 (/) 开头的路径指代应用程序根目录:Paths that start with a tilde-slash (~/) or a slash (/) refer to the app root:

Razor 页面Razor Pages

@await Html.PartialAsync("~/Pages/Folder/_PartialName.cshtml")
@await Html.PartialAsync("/Pages/Folder/_PartialName.cshtml")

MVCMVC

@await Html.PartialAsync("~/Views/Folder/_PartialName.cshtml")
@await Html.PartialAsync("/Views/Folder/_PartialName.cshtml")

以下示例引用使用相对路径的分部视图:The following example references a partial view with a relative path:

@await Html.PartialAsync("../Account/_LoginPartial.cshtml")

或者,也可以使用 RenderPartialAsync 呈现分部视图。Alternatively, you can render a partial view with RenderPartialAsync. 此方法不返回 IHtmlContentThis method doesn't return an IHtmlContent. 它将呈现的输出直接流式传输到响应。It streams the rendered output directly to the response. 因为该方法不返回结果,所以必须在 Razor 代码块内调用它:Because the method doesn't return a result, it must be called within a Razor code block:

@{
    await Html.RenderPartialAsync("_AuthorPartial");
}

由于 RenderPartialAsync 流式传输呈现的内容,因此在某些情况下它可提供更好的性能。Since RenderPartialAsync streams rendered content, it provides better performance in some scenarios. 在性能起关键作用的情况下,使用两种方法对页面进行基准测试,并使用生成更快响应的方法。In performance-critical situations, benchmark the page using both approaches and use the approach that generates a faster response.

同步 HTML 帮助程序Synchronous HTML Helper

PartialRenderPartial 分别是 PartialAsyncRenderPartialAsync 的同步等效项。Partial and RenderPartial are the synchronous equivalents of PartialAsync and RenderPartialAsync, respectively. 但不建议使用同步等效项,因为可能会出现死锁的情况。The synchronous equivalents aren't recommended because there are scenarios in which they deadlock. 同步方法针对以后版本中的删除功能。The synchronous methods are targeted for removal in a future release.

重要

如果需要执行代码,请使用视图组件,而不是使用分部视图。If you need to execute code, use a view component instead of a partial view.

调用 PartialRenderPartial 会导致 Visual Studio 分析器警告。Calling Partial or RenderPartial results in a Visual Studio analyzer warning. 例如,使用 Partial 会产生以下警告消息:For example, the presence of Partial yields the following warning message:

使用 IHtmlHelper.Partial 可能会导致应用程序死锁。Use of IHtmlHelper.Partial may result in application deadlocks. 考虑使用 <分部> 标记帮助程序或 IHtmlHelper.PartialAsync。Consider using <partial> Tag Helper or IHtmlHelper.PartialAsync.

将对 @Html.Partial 的调用替换为 @await Html.PartialAsync分部标记帮助程序Replace calls to @Html.Partial with @await Html.PartialAsync or the Partial Tag Helper. 有关分部标记帮助程序迁移的详细信息,请参阅从 HTML 帮助程序迁移For more information on Partial Tag Helper migration, see Migrate from an HTML Helper.

分部视图发现Partial view discovery

如果按名称(无文件扩展名)引用分部视图,则按所述顺序搜索以下位置:When a partial view is referenced by name without a file extension, the following locations are searched in the stated order:

Razor 页面Razor Pages

  1. 当前正在执行页面的文件夹Currently executing page's folder
  2. 该页面文件夹上方的目录图Directory graph above the page's folder
  3. /Shared
  4. /Pages/Shared
  5. /Views/Shared

MVCMVC

  1. /Areas/<Area-Name>/Views/<Controller-Name>
  2. /Areas/<Area-Name>/Views/Shared
  3. /Views/Shared
  4. /Pages/Shared
  1. /Areas/<Area-Name>/Views/<Controller-Name>
  2. /Areas/<Area-Name>/Views/Shared
  3. /Views/Shared

以下约定适用于分部视图发现:The following conventions apply to partial view discovery:

  • 当分部视图位于不同的文件夹中时,允许使用具有相同文件名的不同分部视图。Different partial views with the same file name are allowed when the partial views are in different folders.
  • 当按名称(无文件扩展名)引用分部视图且分部视图出现在调用方的文件夹和 文件夹中时,调用方文件夹中的分部视图会提供分部视图。When referencing a partial view by name without a file extension and the partial view is present in both the caller's folder and the Shared folder, the partial view in the caller's folder supplies the partial view. 如果调用方文件夹中不存在分部视图,则会从 文件夹中提供分部视图。If the partial view isn't present in the caller's folder, the partial view is provided from the Shared folder. 文件夹中的分部视图称为“共享分部视图” 或“默认分部视图” 。Partial views in the Shared folder are called shared partial views or default partial views.
  • 可以链接分部视图 —如果调用没有形成循环引用,则分部视图可以调用另一个分部视图。Partial views can be chained—a partial view can call another partial view if a circular reference isn't formed by the calls. 相对路径始终相对于当前文件,而不是相对于文件的根视图或父视图。Relative paths are always relative to the current file, not to the root or parent of the file.

备注

分部视图中定义的 Razor section 对父标记文件不可见。A Razor section defined in a partial view is invisible to parent markup files. section 仅对定义它时所在的分部视图可见。The section is only visible to the partial view in which it's defined.

通过分部视图访问数据Access data from partial views

实例化分部视图时,它会获得父视图的 ViewData 字典的副本 。When a partial view is instantiated, it receives a copy of the parent's ViewData dictionary. 在分部视图内对数据所做的更新不会保存到父视图中。Updates made to the data within the partial view aren't persisted to the parent view. 在分部视图中的 ViewData 更改会在分部视图返回时丢失。ViewData changes in a partial view are lost when the partial view returns.

以下示例演示如何将 ViewDataDictionary的实例传递给分部视图:The following example demonstrates how to pass an instance of ViewDataDictionary to a partial view:

@await Html.PartialAsync("_PartialName", customViewData)

还可将模型传入分部视图。You can pass a model into a partial view. 模型可以是自定义对象。The model can be a custom object. 你可以使用 PartialAsync(向调用方呈现内容块)或 RenderPartialAsync(将内容流式传输到输出)传递模型:You can pass a model with PartialAsync (renders a block of content to the caller) or RenderPartialAsync (streams the content to the output):

@await Html.PartialAsync("_PartialName", model)

Razor 页面Razor Pages

示例应用程序中的以下标记来自 Pages/ArticlesRP/ReadRP.cshtml 页面。The following markup in the sample app is from the Pages/ArticlesRP/ReadRP.cshtml page. 此页包含两个分部视图。The page contains two partial views. 第二个分部视图将模型和 ViewData 传入分部视图。The second partial view passes in a model and ViewData to the partial view. ViewDataDictionary 构造函数重载可用于传递新 ViewData 字典,同时保留现有的 ViewData 字典。The ViewDataDictionary constructor overload is used to pass a new ViewData dictionary while retaining the existing ViewData dictionary.

@model ReadRPModel

<h2>@Model.Article.Title</h2>
@* Pass the author's name to Pages\Shared\_AuthorPartialRP.cshtml *@
@await Html.PartialAsync("../Shared/_AuthorPartialRP", Model.Article.AuthorName)
@Model.Article.PublicationDate

@* Loop over the Sections and pass in a section and additional ViewData to 
   the strongly typed Pages\ArticlesRP\_ArticleSectionRP.cshtml partial view. *@
@{
    var index = 0;

    foreach (var section in Model.Article.Sections)
    {
        await Html.PartialAsync("_ArticleSectionRP", 
                                section,
                                new ViewDataDictionary(ViewData)
                                {
                                    { "index", index }
                                });

        index++;
    }
}

Pages/Shared/_AuthorPartialRP.cshtml 是 ReadRP.cshtml 标记文件引用的第一个分部视图:Pages/Shared/_AuthorPartialRP.cshtml is the first partial view referenced by the ReadRP.cshtml markup file:

@model string
<div>
    <h3>@Model</h3>
    This partial view from /Pages/Shared/_AuthorPartialRP.cshtml.
</div>

Pages/ArticlesRP/_ArticleSectionRP.cshtml 是 ReadRP.cshtml 标记文件引用的第二个分部视图:Pages/ArticlesRP/_ArticleSectionRP.cshtml is the second partial view referenced by the ReadRP.cshtml markup file:

@using PartialViewsSample.ViewModels
@model ArticleSection

<h3>@Model.Title Index: @ViewData["index"]</h3>
<div>
    @Model.Content
</div>

MVCMVC

示例应用中的以下标记显示 Views/Articles/Read.cshtml 视图。The following markup in the sample app shows the Views/Articles/Read.cshtml view. 此视图包含两个分部视图。The view contains two partial views. 第二个分部视图将模型和 ViewData 传入分部视图。The second partial view passes in a model and ViewData to the partial view. ViewDataDictionary 构造函数重载可用于传递新 ViewData 字典,同时保留现有的 ViewData 字典。The ViewDataDictionary constructor overload is used to pass a new ViewData dictionary while retaining the existing ViewData dictionary.

@model PartialViewsSample.ViewModels.Article

<h2>@Model.Title</h2>
@* Pass the author's name to Views\Shared\_AuthorPartial.cshtml *@
@await Html.PartialAsync("_AuthorPartial", Model.AuthorName)
@Model.PublicationDate

@* Loop over the Sections and pass in a section and additional ViewData to 
   the strongly typed Views\Articles\_ArticleSection.cshtml partial view. *@
@{
    var index = 0;

    foreach (var section in Model.Sections)
    {
        await Html.PartialAsync("_ArticleSection", 
                                section,
                                new ViewDataDictionary(ViewData)
                                {
                                    { "index", index }
                                });

        index++;
    }
}

Views/Shared/_AuthorPartial.cshtml 是 ReadRP.cshtml 标记文件引用的第一个分部视图:Views/Shared/_AuthorPartial.cshtml is the first partial view referenced by the ReadRP.cshtml markup file:

@model string
<div>
    <h3>@Model</h3>
    This partial view from /Views/Shared/_AuthorPartial.cshtml.
</div>

Views/Articles/_ArticleSection.cshtml 是 Read.cshtml 标记文件引用的第二个分部视图:Views/Articles/_ArticleSection.cshtml is the second partial view referenced by the Read.cshtml markup file:

@using PartialViewsSample.ViewModels
@model ArticleSection

<h3>@Model.Title Index: @ViewData["index"]</h3>
<div>
    @Model.Content
</div>

在运行时,分部视图在父标记文件呈现的输出中呈现,而父标记文件本身在共享的 _Layout.cshtml 内呈现 。At runtime, the partials are rendered into the parent markup file's rendered output, which itself is rendered within the shared _Layout.cshtml. 第一个分部视图呈现文章作者的姓名和发布日期:The first partial view renders the article author's name and publication date:

Abraham LincolnAbraham Lincoln

来自 <共享分部视图文件路径> 的分部视图。This partial view from <shared partial view file path>. 1863 年 11 月 19 日中午 12:00:0011/19/1863 12:00:00 AM

第二个分部视图呈现文章的各部分:The second partial view renders the article's sections:

第一节索引:0Section One Index: 0

八十七年前...Four score and seven years ago ...

第二节索引:1Section Two Index: 1

如今,我们正在进行一场伟大的内战,考验着......Now we are engaged in a great civil war, testing ...

第三节索引:2Section Three Index: 2

然而,从更广泛的意义上说,我们无法奉献...But, in a larger sense, we can not dedicate ...

其他资源Additional resources