レイアウトページを使用しているページにアクセスすると "InvalidOperationException: The layout page '(ページ名)' cannot find the section '(セクション名)' in the content page '(ページ名)'." 例外が発生し、ページが表示されない - ASP.NET Core

レイアウトページを使用しているページにアクセスすると例外が発生しページが表示できない現象について紹介します。

現象

レイアウトページを使用しているページにアクセスすると次の例外が発生します。
エラーメッセージ
InvalidOperationException: The layout page '(ページ名)' cannot find the section '(セクション名)' in the content page '(ページ名)'.

再現コード

ASP.NET Coreアプリケーションを作成し、次のコードを記述します。
Pages/_Layout.cshtml
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link rel="stylesheet" href="Layout.css" />
    <title>@ViewBag.Title</title>
    @RenderSection("MyScript")
</head>
<body>

    <div class="Header">ヘッダ</div>
    <div>
        @RenderBody()
    </div>
    <div class="Footer">フッタ</div>

</body>
</html>
wwwroot/Layout.css
.Header {
  background-color: #ceeaff;
  border: 1px solid #318dff;
}

.Footer {
  background-color: #dddddd;
  border: 1px solid #808080;
}
Pages/Content3.cshtml
@page
@{
    ViewData["Title"] = "Content3";
    Layout = "~/Pages/_Layout.cshtml";
}
<h1>TestPage - Content3</h1>
<p>コンテンツ2のテストページです。</p>
Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();

app.Run();

プロジェクトを実行し、(アプリケーションルートURL)/Contnt3 にアクセスすると、下図のエラーが発生します。

原因

レイアウトページに記述されている @RenderSection("MyScript") メソッドにより、MyScriptセクションを探しますが、 コンテンツページには、MyScriptセクションが定義されていないため、セクションが見つからない旨のエラーが発生します。

対処法1: セクションを定義する

空のセクションを定義する方法です。
Content3 のRazor Pageのコードを下記に変更します。空のMyScriptセクションを定義します。
Pages/Content3.cshtml
@page
@{
    ViewData["Title"] = "Content3";
    Layout = "~/Pages/_Layout.cshtml";
}
@section MyScript{
}

<h1>TestPage - Content3</h1>
<p>コンテンツ2のテストページです。</p>

対処法2: RenderSectionのrequired パラメーターを変更する

レイアウトページのRenderSection() メソッドは、2つの引数をとるメソッドもあり、第二引数にセクションの存在が必須かを指定するパラメーターがあります。 このパラメーターを false に設定することで、コンテンツページにセクションが定義されていない場合でも例外が発生しないようにできます。
Pages/_Layout.cshtml
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <link rel="stylesheet" href="Layout.css" />
    <title>@ViewBag.Title</title>
    @RenderSection("MyScript",false)
</head>
<body>

    <div class="Header">ヘッダ</div>
    <div>
        @RenderBody()
    </div>
    <div class="Footer">フッタ</div>

</body>
</html>

動作確認

上記のどちらかの対処法を実施すると、コンテンツページが表示される動作になります。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-07-27
作成日: 2022-07-26
iPentec all rights reserverd.