しばやん雑記

ASP.NET とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET Core MVC の Razor で使える Tag Helpers のメモ書き

ちょっと真面目に ASP.NET Core MVC の Razor を書いている時に、そういえば Tag Helpers の書き方をあまり勉強していなかったと気が付いたので、これを気に個人的によく使いそうな部分だけメモります。

例によってドキュメントがちゃんと用意されているので、まずは良く読んでおきました。

基本的には asp-* という属性を使って書ける Html Helper です。HTML のタグとシームレスに統合されていて、構造を崩さずに書けるので Tag Helpers は最高に便利です。

cshtml を開いても Tag Helpers のシンタックスハイライトが有効にならない場合には、Visual Studio の拡張機能から Razor Language Services をインストールすると直ります。

f:id:shiba-yan:20170725140941p:plain

最初は入ってたと思うのですが、アップデートのタイミングなどで無効化されたのかもしれません。

Visual Studio を再起動後に cshtml を再度開くと正しくハイライト表示されるようになります。

f:id:shiba-yan:20170725144138p:plain

普通のタグの場合とは色が異なっているので、わかりやすくなってます。

ビューを書いている時に Tag Helpers かどうかを判別する方法として、IntelliSense のアイコンに @ が付いているかというのがあります。

f:id:shiba-yan:20170725145314p:plain

div タグは HTML で定義された要素ですが、Tag Helper としても実装されているので @ が付いています。

基礎知識としてはこのくらいにして、以下は実際に Tag Helpers を使って書く時のメモです。

リンク生成 (a)

<!-- href = /home/about -->
<a asp-controller="Home" asp-action="About">About me</a>

<!-- href = /home/about/123 -->
<a asp-controller="Home" asp-action="About" asp-route-id="123">About me</a>

<!-- href = /home/about#top -->
<a asp-controller="Home" asp-action="About" asp-fragment="top">Go to Top</a>

<!-- href = https://hostname/home/about -->
<a asp-controller="Home" asp-action="About" asp-protocol="https">Https link</a>

<!-- href = https://www.example.com/home/about -->
<a asp-controller="Home" asp-action="About" asp-protocol="https" asp-host="www.example.com">Absolute Path</a>

リソース参照 (img / link / script)

<!-- src = /img/top.png?v=SHA256HASH -->
<img src="~/img/top.png" asp-append-version="true" />

<!-- href のファイルを読み込めなかった時は asp-fallback-href を読む -->
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/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" />

<!-- src のファイルを読み込めなかった時は asp-fallback-src を読む -->
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
        asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
        asp-fallback-test="window.jQuery">
</script>

フォーム表示 (form / input / select など)

<!-- action = /user/login -->
<form asp-controller="Login" asp-action="User" method="post">

    <!-- type="email" id="Email" name="Email" -->
    <input asp-for="Email" />

    <!-- type="password" id="Password" name="Password" -->
    <input asp-for="Password" />

    <button>Login</button>

</form>

<!-- CSRF 用トークンを自動出力しない -->
<form asp-antiforgery="false">
  <button>submit</button>
</form>

<!-- formaction = /forms/delete/123 -->
<button asp-controller="Forms" asp-action="Delete" asp-route-id="123">Delete</button>

<!-- asp-items には IEnumerable<SelectListItem> -->
<select asp-for="Favorite" asp-items="AllItems">
</select>

バリデーションエラー表示 (div / span)

<!-- 全てのエラーを表示 -->
<div asp-validation-summary="All"></div>

<!-- モデルに対してのエラーのみ -->
<div asp-validation-summary="ModelOnly"></div>

<!-- 指定したキーのエラーのみ -->
<span asp-validation-for="Email"></span>

Core MVC 独自 (environment)

<!-- ASP.NET Core 1.1 まで -->
<environment names="Production,Staging">
  <link rel="stylesheet" href="~/site.min.css" />
</environment>
<environment names="Development">
  <link rel="stylesheet" href="~/site.css" />
</environment>

<!-- ASP.NET Core 2.0 から -->
<environment Exclude="Development">
  <link rel="stylesheet" href="~/site.min.css" />
</environment>
<environment Include="Development">
  <link rel="stylesheet" href="~/site.css" />
</environment>

Tag Helper を自作する

新しい要素の追加だけではなく、既存の要素に属性を追加して動作のカスタマイズなど、割と柔軟に作ることが出来る。はっきり言ってかなり賢い。

サンプルにある Condition Tag Helper は普通に欲しい。if を毎回書いて出し分けるのは面倒。