ASP.NET Core の部分ビュー

作成者: Steve SmithMaher JENDOUBIRick AndersonScott Sauber

部分ビューとは、別のマークアップ ファイルの出力表示の中に HTML 出力をレンダリングする、@page ディレクトリのない Razor マークアップ ファイル (.cshtml) です。

"部分ビュー" という用語は、マークアップ ファイルが "ビュー" と呼ばれている MVC アプリか、マークアップ ファイルが "ページ" と呼ばれている Razor アプリの開発時に使用されます。 このトピックでは総称として、MVC ビューと Razor Pages ページを "マークアップ ファイル" と呼びます。

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

部分ビューを使用する状況

部分ビューは、次の場合に効果的な方法です。

  • 大規模なマークアップ ファイルをより小さなコンポーネントに分割します。

    複数の論理パーツで構成された大規模かつ複雑なマークアップ ファイルでは、各パーツが部分ビューに分かれた状態で操作すると便利です。 全体のページ構造と部分ビューへの参照がマークアップのみに含まれるため、マークアップ ファイルのコードは管理性に優れています。

  • マークアップ ファイル間で共通するマークアップ コンテンツの重複を減らします。

    マークアップ ファイル間で同じマークアップ要素が使用されている場合、1 つの部分ビュー ファイルとなり、部分ビューによってマークアップ コンテンツの重複が除去されます。 部分ビュー内でマークアップが変更された場合、その部分ビューを使用しているマークアップ ファイルの出力表示が更新されます。

共通するレイアウト要素を維持するために、部分ビューを使用しないでください。 共通するレイアウト要素は、_Layout.cshtml ファイルで指定する必要があります。

マークアップを表示するために、複雑な表示ロジックやコード実行が必要になる場合は、部分ビューを使用しないでください。 部分ビューの代わりに、ビュー コンポーネントを使用してください。

部分ビューを宣言する

部分ビューは、Views フォルダー (MVC) または Pages フォルダー (Razor Pages) 内に保持されている @page ディレクティブ内の .cshtml マークアップ ファイルです。

ASP.NET Core MVC では、コントローラーの ViewResult が、ビューまたは部分ビューのどちらかを返すことができます。 Razor Pages では、PageModel によって、PartialViewResult オブジェクトとして表される部分ビューを返すことができます。 部分ビューの参照と表示については、「部分ビューを参照する」セクションで説明します。

MVC ビューやページ レンダリングとは異なり、部分ビューでは _ViewStart.cshtml が実行されません。 _ViewStart.cshtml に関する詳細については、「ASP.NET Core でのレイアウト」をご覧ください。

部分ビューのファイル名は、多くの場合アンダースコア (_) から始まります。 この名前付け規則は必須ではありませんが、ビューおよびページと部分ビューを視覚的に区別するのに役立ちます。

部分ビューは、Views フォルダー内に保持される .cshtml マークアップ ファイルです。

コントローラーの ViewResult は、ビューまたは部分ビューのどちらかを返すことができます。 部分ビューの参照と表示については、「部分ビューを参照する」セクションで説明します。

MVC ビューのレンダリングとは異なり、部分ビューでは _ViewStart.cshtml は実行されません。 _ViewStart.cshtml に関する詳細については、「ASP.NET Core でのレイアウト」をご覧ください。

部分ビューのファイル名は、多くの場合アンダースコア (_) から始まります。 この名前付け規則は必須ではありませんが、ビューと部分ビューを視覚的に区別するのに役立ちます。

部分ビューを参照する

Razor Pages の PageModel で部分ビューを使用する

ASP.NET Core 2.0 または 2.1 では、次のハンドラー メソッドによって、応答に対して AuthorPartialRP.cshtml の部分ビューがレンダリングされます:

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

ASP.NET Core 2.2 以降では、別の方法としてハンドラー メソッドによって、Partial メソッドを呼び出して PartialViewResult オブジェクトを生成することもできます。

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

マークアップ ファイルで部分ビューを使用する

マークアップ ファイル内で、部分ビューを参照する方法はいくつかあります。 アプリでは、次の非同期レンダリング手法のいずれかを使用することをお勧めします。

マークアップ ファイル内で、部分ビューを参照するには、次の 2 つの方法があります。

アプリでは、非同期の HTML ヘルパーを使用することをお勧めします。

部分タグ ヘルパー

部分タグ ヘルパーでは、ASP.NET Core 2.1 以降が必要です。

部分タグ ヘルパーでは、非同期でコンテンツをレンダリングして、HTML のような構文を使用します。

<partial name="_PartialName" />

ファイル拡張子がある場合、タグ ヘルパーは、部分ビューを呼び出すマークアップ ファイルと同じフォルダー内に必ず配置されている部分ビューを参照します。

<partial name="_PartialName.cshtml" />

次の例では、アプリ ルートから部分ビューを参照しています。 チルダとスラッシュ (~/) またはスラッシュ (/) から始まるパスは、次のようにアプリ ルートを参照します。

Razor Pages

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

MVC

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

次の例では、相対パスを使って部分ビューを参照しています。

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

詳細については、「ASP.NET Core の部分タグ ヘルパー」を参照してください。

非同期の HTML ヘルパー

HTML ヘルパーを使用している場合、ベスト プラクティスは PartialAsync を使用することです。 PartialAsync は、Task<TResult> でラップされた IHtmlContent 型を返します。 待機中の呼び出しの前に @ 文字を付与することで、メソッドが参照されます。

@await Html.PartialAsync("_PartialName")

ファイル拡張子がある場合、HTML ヘルパーは、部分ビューを呼び出すマークアップ ファイルと同じフォルダー内に必ず配置されている部分ビューを参照します。

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

次の例では、アプリ ルートから部分ビューを参照しています。 チルダとスラッシュ (~/) またはスラッシュ (/) から始まるパスは、次のようにアプリ ルートを参照します。

Razor Pages

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

MVC

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

次の例では、相対パスを使って部分ビューを参照しています。

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

代わりに、RenderPartialAsync を使って部分ビューをレンダリングすることもできます。 このメソッドは IHtmlContent を返しません。 レンダリングされた出力を直接応答にストリーミングします。 メソッドが結果を返さないため、Razor コード ブロック内で呼び出す必要があります。

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

RenderPartialAsync は表示されるコンテンツをストリーム配信するため、一部のシナリオではより高いパフォーマンスが得られます。 パフォーマンスが重要な場合には、両方の手法を使用してページのベンチマークを実行し、より迅速に応答を生成する手法を採用します。

同期の HTML ヘルパー

PartialRenderPartial はそれぞれ、PartialAsyncRenderPartialAsync の同期に相当します。 デッドロックが発生するシナリオがあるため、同期に相当する機能はお勧めしません。 同期メソッドは、将来のリリースでは削除対象になります。

重要

コードを実行する必要がある場合は、部分ビューの代わりにビュー コンポーネントを使用してください。

Partial または RenderPartial を呼び出すと、Visual Studio アナライザーの警告が発生します。 たとえば、Partial を指定すると、次の警告メッセージが生成されます。

IHtmlHelper.Partial を使用すると、アプリケーションのデッドロックが発生する可能性があります。 <部分>タグ ヘルパーまたは IHtmlHelper.PartialAsync を使用することを検討してください。

@Html.Partial の呼び出しを、@await Html.PartialAsync または部分タグ ヘルパーに置き換えます。 部分タグ ヘルパーの移行の詳細については、「HTML ヘルパーから移行する」を参照してください。

部分ビューの検出

部分ビューがファイル拡張子を指定せずに名前で参照された場合、所定の順序で次の場所が検索されます。

Razor Pages

  1. 現在実行中のページのフォルダー
  2. ページのフォルダーの上にあるディレクトリ グラフ
  3. /Shared
  4. /Pages/Shared
  5. /Views/Shared

MVC

  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

部分ビューの検索には、次の規則が適用されます。

  • 部分ビューが異なるフォルダー内にある場合は、同じファイル名の別の部分ビューが許可されます。
  • ファイル拡張子を指定せずに部分ビューを名前で参照しており、かつ、部分ビューが呼び出し元のフォルダーと Shared フォルダーの両方に存在する場合、呼び出し元のフォルダーにある部分ビューが、部分ビューとして機能します。 部分ビューが呼び出し元のフォルダーに存在しない場合、部分ビューは Shared フォルダーから提供されます。 Shared フォルダーの部分ビューは、"共有の部分ビュー" または "既定の部分ビュー" と呼ばれます。
  • 部分ビューは "チェーン化" されることがあります。つまり、呼び出しによって循環参照が形成されない場合、部分ビューが別の部分ビューを呼び出す場合があります。 相対パスは常に、ファイルのルートや親ではなく、現在のファイルを基準とします。

Note

部分ビューで定義されている Razorsection は、親のマークアップ ファイルには表示されません。 section は定義されている部分ビューにのみ表示されます。

部分ビューからデータにアクセスする

部分ビューがインスタンス化されると、親の ViewData ディクショナリのコピーを取得します。 親ビュー内のデータに対して行われた更新は、親ビューでは保持されません。 部分ビューで変更された ViewData は、部分ビューから返されるときに失われます。

次の例では、ViewDataDictionary のインスタンスを部分ビューに渡す方法を示します。

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

部分ビューにモデルを渡すことができます。 モデルは、カスタム オブジェクトでもかまいません。 PartialAsync (呼び出し元にコンテンツのブロックを表示する) または RenderPartialAsync (コンテンツを出力にストリーム配信する) を使って、モデルを渡すことができます。

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

Razor Pages

サンプル アプリの次のマークアップは、Pages/ArticlesRP/ReadRP.cshtml ページからのものです。 ページには、2 つの部分ビューが含まれています。 2 番目の部分ビューは、モデルと ViewData を部分ビューに渡します。 ViewDataDictionary のコンストラクター オーバーロードは、既存の ViewData ディクショナリを維持したまま、新しい ViewData ディクショナリを渡すために使用されます。

@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 マークアップ ファイルによって参照される最初の部分ビューです。

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

Pages/ArticlesRP/_ArticleSectionRP.cshtml は、ReadRP.cshtml マークアップ ファイルによって参照される 2 番目の部分ビューです。

@using PartialViewsSample.ViewModels
@model ArticleSection

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

MVC

サンプル アプリの次のマークアップは、Views/Articles/Read.cshtml ビューを示しています。 ビューには、2 つの部分ビューが含まれています。 2 番目の部分ビューは、モデルと ViewData を部分ビューに渡します。 ViewDataDictionary のコンストラクター オーバーロードは、既存の ViewData ディクショナリを維持したまま、新しい ViewData ディクショナリを渡すために使用されます。

@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 は、Read.cshtml マークアップ ファイルによって参照される最初の部分ビューです。

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

Views/Articles/_ArticleSection.cshtml は、Read.cshtml マークアップ ファイルによって参照される 2 番目の部分ビューです。

@using PartialViewsSample.ViewModels
@model ArticleSection

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

実行時に、この部分は、(それ自体は共有されている _Layout.cshtml 内にレンダリングされる) 親マークアップ ファイルのレンダリングされた出力にレンダリングされます。 最初の部分ビューは、記事の作成者の名前と発行日を表示します。

アブラハム リンカーン

この部分ビューは<共有されている部分ビューのファイル パス>が元になっている。 1863 年 11 月 19 日 12 時 00 分 00 秒

2 番目の部分ビューは、次に示す記事のセクションを表示します。

セクション 1 のインデックス: 0

87 年前...

セクション 2 のインデックス: 1

大きな内紛の渦中で、試した...

セクション 3 のインデックス: 2

しかし、広義では、我々が献身することはできない...

その他のリソース