前回、作成したビューには meta、header タグを記述していないのに、ブラウザ表示した時には、meta、header が生成されています。どういうことでしょうか。その答えは、レイアウトです。
レイアウト
ASP.NET Core MVC では、ページやビューはレイアウト・デザイン(例えば css、html)、コード(例えば javascript)を共有します。
- 共通のレイアウトを使用
- ディレクティブを共有
- ページまたはビューを表示する前に、共通のコードを実行
下図を見るとレイアウトのイメージを掴めるかもしれません。

上記の共有要素をすべて Layout ファイルで定義することで、アプリ内で使用する任意のビューで参照できるようになります。
ASP.NET Core プロジェクト作成時には、既定のレイアウトである _Layout.cshtml ファイルが作成されています。
_Layout.cshtml
ファイル位置

_Layout のコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - BlueOwl.DrawingMemory.WebMvc</title> <!-- 環境タグ:ホスティング環境が Staging or Production or Development によりコンテンツが切り替わります。後続で説明します。 --> <environment include="Development"> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" /> </environment> <environment exclude="Development"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css" asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" crossorigin="anonymous" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" /> </environment> <link rel="stylesheet" href="~/css/site.css" /> </head> <body> <header> <!-- レイアウト図の Header 部分にあたる箇所です --> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">BlueOwl.DrawingMemory.WebMvc</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"> <partial name="_LoginPartial" /> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </li> </ul> </div> </div> </nav> </header> <div class="container"> <partial name="_CookieConsentPartial" /> <main role="main" class="pb-3"> <!-- ビューのコンテンツがレンダリングされます。 --> @RenderBody() </main> </div> <!-- レイアウト図の Footer 部分にあたる箇所です --> <footer class="border-top footer text-muted"> <div class="container"> © 2019 - BlueOwl.DrawingMemory.WebMvc - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> </div> </footer> <!-- 環境タグ:ホスティング環境が Staging or Production or Development によりコンテンツが切り替わります。後続で説明します。 --> <environment include="Development"> <script src="~/lib/jquery/dist/jquery.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script> </environment> <environment exclude="Development"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" asp-fallback-src="~/lib/jquery/dist/jquery.min.js" asp-fallback-test="window.jQuery" crossorigin="anonymous" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="> </script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js" asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js" asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal" crossorigin="anonymous" integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o"> </script> </environment> <script src="~/js/site.js" asp-append-version="true"></script> <!-- 1 つ以上のセクションを参照することができます。 --> @RenderSection("Scripts", required: false) </body> </html> |
ポイント箇所にはコメントを追加しています。列挙すると次になります。
-
- @RenderSection(“Scripts”, required: false)
- @RenderBody()
- 環境タグ
これら順に紹介します。また、ASP.NET Core 2.2 ではデザインフレームワークとして Bootstrap v4 がデフォルトで導入されています。タグで指定されている class の多くは Bootstrap の class です。
レイアウトの指定
ビューによって複数のレイアウトに切り替え可能です。つまり、自作したレイアウトに切り替えることもできます。
1 2 3 4 5 6 7 8 9 |
@{ // 拡張子を除いた名前を指定します(部分パス) ex) _Layout.cshtml -> _Layout // ※完全パス(/Views/Shared/_Layout.cshtml)の指定も可能です。 // 下記のように自作したレイアウトを指定可能です。 // 省略した場合は、_Layout.cshtml が選択されます。 Layout = "_Layout_Owl"; } <h2>DrawingController.Index</h2> <h3>hello world.</h3> |
レイアウトの検出
開発当初は、ビューがありませんというエラーが発生するかもしれません。その時に Razor ビュー エンジンの標準の検出プロセスを覚えておくと、エラー解決に役立つ場合があります。レイアウトの検出プロセスと部分ビューの検出プロセスは同じです。
@RenderSection
レイアウトは、必要に応じて RenderSection を呼び出すことで、1 つ以上のセクションを参照することができます。 セクションは、特定のページ要素の配置場所を整理する方法を提供します。 RenderSection の呼び出しごとに、そのセクションを必須またはオプションにするかどうかを指定できます。
ASP.NET Core 若しくは、プログラミング初めての人で、この説明を理解できる人はすごく優秀だと思います(僕は無理かな)。
コードをよく見る方が、イメージが掴めるかもしれません。
@RenderSection(“Scripts”, required: false)
第1引数に “Scripts” 、第2引数に required: false 、つまり、スクリプトをレンダリングするセクション + 必須ではない(無くてもエラーにならない)ということです。そのままですけど。。。
今、よくわからなくても、安心してください。javascript の実装が必要なビューを作成すると、あーなるほど!となりますから。一応、公式サイトにサンプルがあったので載せておきます。
1 2 3 |
@section Scripts { <script type="text/javascript" src="/scripts/main.js"></script> } |
上記の View コードが、_Layout.cshtml の @RenderSection 埋め込まれるイメージです。
1 2 3 4 |
<!-- _Layout.cshtml --> <script src="~/js/site.js" asp-append-version="true"></script> <!-- @RenderSection("Scripts", required: false) --> <script type="text/javascript" src="/scripts/main.js"></script> |
また、なぜ @RenderBody() の後のこの位置に @RenderSection(“Scripts”, required: false) を配置するのか、Web 初心者の方には結構重要だったりします。その辺りは、次回以降でビューを作成するときに触れたいと思います。
@RenderBody()
すべてのレイアウトで RenderBody を呼び出す必要があります。 RenderBody への呼び出しが配置されると、ビューのコンテンツがレンダリングされます。
「レイアウトの指定」での View コードが、_Layout.cshtml の @RenderBody 埋め込まれるイメージです。
1 2 3 4 5 6 7 8 9 10 |
<!-- _Layout.cshtml --> <div class="container"> <partial name="_CookieConsentPartial" /> <main role="main" class="pb-3"> <!-- @RenderBody() --> <!-- ↓ ビューのコンテンツがレンダリングされます。 --> <h2>DrawingController.Index</h2> <h3>hello world.</h3> </main> </div> |
まだ、僕は見れていないですが、このあたりのソースが RenderBody に関係するところでしょうか。
environmentタグ
環境タグ ヘルパーは、現在のホスティング環境に基づき、囲まれたコンテンツを条件付きで表示します。 環境タグ ヘルパーの 1 つの属性 names は、環境名のコンマ区切りリストです。 指定された環境名のいずれかが現在の環境と一致する場合、囲まれたコンテンツが表示されます。
指定する name は、一般的に「Staging」「Production」「Development」です。
Staging、Production
例えば、トランスパイル済 + バンドル済の javascript の読み込み
Development
Development では、デバッグがしやすいバンドル前の javascript の読み込み
「Staging」「Production」「Development」については、↓ で紹介しています(ASP.NET Core で複数の環境を使用)
プライマリ スクリプト ファイルの指定
environmentタグを使用して、下記のようにプライマリ スクリプト ファイルの指定することができます。
1 2 3 4 5 6 |
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js" asp-fallback-src="~/lib/jquery/dist/jquery.min.js" asp-fallback-test="window.jQuery" crossorigin="anonymous" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT"> </script> |
Content Delivery Network (CDN) が使用できない場合は、asp-fallback-src でプライマリ側でエラーが発生した場合にフォールバックするスクリプトタグの URL を指定します。その場合、ローカルのスクリプトを指定することが多いと思いますが、asp-suppress-fallback-integrity=”true” にすることにより整合性チェックをバイパスできます。
次回から、実装に戻ります。
また、本格的にビュー実装に入るにあたり、webpack + Babel + TypeScript のインストール・設定を近々紹介する予定です。