ASP.NET Core3.0 RazorPages事始め(11)番外編 - _Layout.cshtml/_ViewImports.cshtml/ViewStart.cshtml


## はじめに

これまで、10回にわたって公式ページのチュートリアルをやってきたわけですが、ちょっと書き足りない部分があるので、番外編ということで、あと数回、ASP.NET Core Razor Pages について書いていこうとと思います。

さて、今回は、`dotnet new webapp` コマンドで自動で作成される、以下のファイルについて、見ていこうと思います。


-  /Pages/Shared/_Layout.cshtml
-  /Pages/_ViewImports.cshtml
-  /Pages/_ViewStart.cshtm

以前の記事とすこし被るところがありますが、ご容赦を。

## /Pages/Shared/_Layout.cshtml

このファイルは、アプリケーションで利用するhtmlのテンプレートが定義されています。

一部を抜粋して示します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Movie</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        ...
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - RazorPagesMovie - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>
```

あっ、htmlタグの lang属性は、'ja' に変更しています。

ここで、注目するのは、3点ですね。

### ViewDataディクショナリ

一点目は、この記述。

```
    <title>@ViewData["Title"] - Movie</title>
```

@マークで始まるのが、ASP.NET Coreの Razor構文です。
ViewDate ディクショナリの "Title"キーに対応する値をtitle要素に設定してます。

例えば、create.cshtmlの先頭には、次のような記述があります。

```
@{
    ViewData["Title"] = "Create";
}
```

ですから、

```
    <title>Create - Movie</title>
```

と展開され、ブラウザのタブには "Create - Movie" が表示されることのなります。

### @Render.Body()

二点目は、            

```
@RenderBody()
```

です。この部分に、各ページ(index.cshtmlやCreate.cshtmlなど)で記述した内容が挿入されレンダリングされることになります。

そういえば、`ViewBag`プロパティはないんですね。`ViewData`よりも`ViewBag`のほうが好きだったんですけどね。

### @RenderSection()

3点目は、最後のほうにあるこの行。

```
    @RenderSection("Scripts", required: false)
```

これは、各ページで記述された以下のような部分をレンダリングすることになります。

```
@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
```

body要素の最後で、javascriptを読み込みたい時に利用します。

この例では、_ValidationScriptsPartial.cshtml ファイルを読み込んでいます。このファイルには次のような記述があるので、クライアント側検証で必要となるavaScriptファイルが読み込まれます。

```html
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
```

### その他

そのほか、`asp-area` `asp-page` といった見慣れない属性がありますが、これはまた別の機会に。


そういえば、ネットで調べていたら、次のようなコードがありました。

```html
    <environment include="Development">
        <link rel="stylesheet" href="~/css/bootstrap.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="~/css/bootstrap.min.css" />
    </environment>
```

環境変数の値によって、読み込むCSSを切り替えています。ASP.NET Core 2.0 の時は、このようなコードを自動生成していたようです。JavaScriptの読み込みも同様です。

まあ、開発時に、minification していない `bootstrap.css` や `jquery.js` が必要かと言われれば、普通の開発者には不要なので、ASP.NET Core3.0で変更したのでしょうね。



## /Pages/_ViewImports.cshtml

_ViewImports.cshtmlの内容は以下の通りです。

```
@using RazorPagesMovie
@namespace RazorPagesMovie.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
```

各ページのcshtmlをレンダリングする時に、この cshtmlがインポートされるようです。
ここで、@usingディレクティブで `RazorPagesMovie`名前空間を指定しているので、個別のcshtmlでは、いちいち名前空間を指定しなくて、クラス名などが使えるようになります。

@namespace ディレクティブは、それぞれのページの名前空間を指定してるようです。正確な意味がまだわかってません。

最後の行の

```
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
```

では、cshtmlで利用するタグヘルパーというものを提供するアセンブリを指定しています。
もし、自分でタグヘルパーをベルアセンブリとして作ったら、ここにそのアセンブリを追加すれば使えることになります。


## /Pages/_ViewStart.cshtml

以下が、_ViewStart.cshtml の内容です。

```
@{
    Layout = "_Layout";
}
```

これだけです。

この指定で、_Layout.cshtmlがマスターテンプレートページとして利用されるます。

マスターページを _Layout.cshtml 以外のファイルに変えたかったら、ここを変更すればOKということですね。まあ変えることはないと思いますが。

ちなみに、特定のcshtmlで、別のテンプレートページを使い分けたい場合は、その cshtmlファイルの先頭で、

```
@{
    Layout = "_myLayout";
}
```

と書けば、_myLayout.cshtmlが利用されます。


次のように書けば、テンプレート利用されません。この場合は、`<!DOCTYPE html>` からすべてのhtmlを書くことになります。


```
@{
    Layout = null";
}
```