ASP.NET Core의 부분 보기Partial views in ASP.NET Core

작성자: Steve Smith, Luke Latham, Maher JENDOUBI, Rick AndersonScott SauberBy Steve Smith, Luke Latham, Maher JENDOUBI, Rick Anderson, and Scott Sauber

부분 보기는 다른 태그 파일의 렌더링된 출력 내에서 HTML 출력을 렌더링하는 Razor 태그 파일( .cshtml)입니다.A partial view is a Razor markup file (.cshtml) that renders HTML output within another markup file's rendered output.

부분 보기라는 용어는 MVC 앱(태그 파일을 보기라고 부름) 또는 Razor 페이지 앱(태그 파일을 페이지라고 부름)을 개발할 때 사용됩니다.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 페이지의 페이지를 태그 파일이라고 부릅니다.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 페이지)에서 유지 관리되는 .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 페이지에서 PageModelPartialViewResult 개체로 표시되는 부분 보기를 반환할 수 있습니다.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 페이지 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 도우미를 사용할 때 가장 좋은 방법은 PartialAsync를 사용하는 것입니다.When using an HTML Helper, the best practice is to use PartialAsync. PartialAsyncTask<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. 이 메서드는 IHtmlContent를 반환하지 않습니다.This 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.

Partial 또는 RenderPartial 호출 시 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.
  • 파일 확장명 없이 이름으로 부분 보기를 참조하면서 부분 보기가 호출자의 폴더와 Shared 폴더 모두에 존재할 경우 호출자 폴더에 위치해 있는 부분 보기가 부분 보기를 제공합니다.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. 호출자의 폴더에 부분 보기가 존재하지 않으면 부분 보기는 Shared 폴더에서 제공됩니다.If the partial view isn't present in the caller's folder, the partial view is provided from the Shared folder. Shared 폴더의 부분 보기를 공유 부분 보기 또는 기본 부분 보기라고 합니다.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.cshtmlReadRP.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.cshtmlReadRP.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.cshtmlRead.cshtml 태그 파일에서 참조하는 첫 번째 부분 보기입니다.Views/Shared/_AuthorPartial.cshtml is the first partial view referenced by the Read.cshtml markup file:

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

Views/Articles/_ArticleSection.cshtmlRead.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>.This partial view from <shared partial view file path>. 1863/11/19 12:00:00 AM11/19/1863 12:00:00 AM

두 번째 부분 보기는 문서의 섹션을 렌더링합니다.The second partial view renders the article's sections:

섹션 1 인덱스: 0Section One Index: 0

Four score and seven years ago ...Four score and seven years ago ...

섹션 2 인덱스: 1Section Two Index: 1

Now we are engaged in a great civil war, testing ...Now we are engaged in a great civil war, testing ...

섹션 3 인덱스: 2Section Three Index: 2

But, in a larger sense, we can not dedicate ...But, in a larger sense, we can not dedicate ...

추가 자료Additional resources