ASP.NET Core のタグ ヘルパー

作成者: Rick Anderson

タグ ヘルパーとは

タグ ヘルパーを使うと、Razor ファイルでの HTML 要素の作成とレンダリングに、サーバー側コードを組み込むことができます。 たとえば、組み込みの ImageTagHelper では、イメージ名にバージョン番号を追加することができます。 イメージが変更されるたびに、サーバーはイメージに対して新しい一意のバージョンを生成するため、クライアントは (キャッシュされた古いイメージではなく) 現在のイメージを確実に取得できます。 フォームやリンクの作成、資産の読み込みなど、一般的なタスクの組み込みのタグ ヘルパーは数多くあります。パブリック GitHub リポジトリで NuGet パッケージとして使用することもできます。 タグ ヘルパーは C# で作成され、要素名、属性名、または親タグに基づく HTML 要素をターゲットとします。 たとえば、LabelTagHelper 属性が適用されている場合、組み込みの LabelTagHelper では HTML <label> 要素をターゲットとすることができます。 HTML ヘルパーに慣れている方は、タグ ヘルパーを使用すると、Razor ビューで HTML と C# の間の明示的な切り替えが減ることがわかります。 多くの場合、HTML ヘルパーでは特定のタグ ヘルパーの代替方法が提供されますが、タグ ヘルパーを HTML ヘルパーの代わりに使用することはできないことと、各 HTML ヘルパーに対応するタグ ヘルパーがないことを認識することが重要です。 2 つの違いの詳細については、「タグ ヘルパーと HTML ヘルパーの比較」を参照してください。

タグ ヘルパーで提供されるもの

HTML 適した開発エクスペリエンス

ほとんどの場合、タグ ヘルパーを使用した Razor マークアップは標準の HTML のように見えます。 HTML、CSS、JavaScript に精通しいているフロントエンドのデザイナーは、C# Razor 構文を学習しなくても Razor を編集できます。

HTML と Razor マークアップを作成するための豊富な IntelliSense 環境

これは、Razor ビューのマークアップをサーバー側で作成する従来の手法である HTML ヘルパーとは非常に対象的です。 2 つの違いの詳細については、「タグ ヘルパーと HTML ヘルパーの比較」を参照してください。 IntelliSense 環境については、「Intellisense でのタグ ヘルパーのサポート」を参照してください。 Razor C# 構文に慣れている開発者であっても、C# Razor マークアップを記述するより、タグ ヘルパーを使用する方が生産性を高めることができます。

サーバーでのみ得られる情報を使用して、生産性を高め、より堅牢で信頼性の高い保守可能なコードを生成する方法

たとえば、画像の更新について、従来は画像を変更するときに画像の名前を変更する方法が繰り返されてきました。 パフォーマンス上の理由から、イメージを積極的にキャッシュする必要があり、イメージの名前を変更しない限り、クライアントが古いコピーを取得する危険性があります。 これまでは、イメージの編集後に、名前を変更する必要があり、Web アプリでのイメージへの各参照を更新する必要がありました。 これは非常に労力がかかるだけでなく、エラーが発生しやくなります (参照が見つからなかったり、誤って違う文字列を入力したりすることなどがあります)。組み込み ImageTagHelper は、あなたの代わりにこれを自動的に行います。 ImageTagHelper ではイメージ名にバージョン番号を追加できるため、イメージが変更されるたびに、サーバーはそのイメージに対して新しい一意のバージョンを自動的に生成します。 クライアントは現在のイメージを確実に取得できます。 ImageTagHelper を使用することで、このような堅牢性と省力化を基本的に自由に実現できます。

ほとんどの組み込みタグ ヘルパーは、標準の HTML 要素をターゲットとし、要素に対してサーバー側の属性を提供します。 たとえば、Views/Account フォルダーの多くのビューで使用される <input> 要素には、asp-for 属性が含まれて この属性は、指定されたモデル プロパティの名前をレンダリングされる HTML に抽出します 次のモデルの Razor ビューについて考えてみましょう。

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}

Razor マークアップは次のとおりです。

<label asp-for="Movie.Title"></label>

次の HTML が生成されます。

<label for="Movie_Title">Title</label>

asp-for 属性は、LabelTagHelperFor プロパティで使用できます。 詳しくは、タグ ヘルパーの作成に関するページをご覧ください。

タグ ヘルパーのスコープの管理

タグ ヘルパーのスコープは、@addTagHelper@removeTagHelper、"!" オプトアウト文字の組み合わせによって制御されます。

@addTagHelper でタグ ヘルパーを使用可能にする

AuthoringTagHelpers という名前の新しい ASP.NET Core Web アプリを作成する場合、以下の Views/_ViewImports.cshtml ファイルがプロジェクトに追加されます。

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

@addTagHelper ディレクティブにより、ビューでタグ ヘルパーが使用可能になります。 この場合、ビュー ファイルは Pages/_ViewImports.cshtml であり、既定では Pages フォルダーとサブフォルダーのすべてのファイルによって継承され、タグ ヘルパーが使用可能になります。 上記のコードではワイルドカード構文 ("*") を使用して、指定されたアセンブリ (Microsoft.AspNetCore.Mvc.TagHelpers) 内のすべてのタグ ヘルパーが、Views ディレクトリまたはサブディレクトリ内のすべてのビュー ファイルで使用可能になるように指定します。 @addTagHelper の後の最初のパラメーターでは読み込むタグ ヘルパーを指定し (すべてのタグ ヘルパーに対して "*" を使用)、2 番目のパラメーター "Microsoft.AspNetCore.Mvc.TagHelpers" ではタグ ヘルパーを含むアセンブリを指定します。 Microsoft.AspNetCore.Mvc.TagHelpers は、組み込み ASP.NET Core タグ ヘルパーのアセンブリです。

すべてのタグ ヘルパーをこのプロジェクト (AuthoringTagHelpers という名前のアセンブリを作成する) で公開するには、以下を使用します。

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

プロジェクトに既定の名前空間がある EmailTagHelper が含まれている場合は (AuthoringTagHelpers.TagHelpers.EmailTagHelper)、タグ ヘルパーの完全修飾名 (FQN) を指定できます。

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers

FQN を使用してビューにタグ ヘルパーを追加するには、最初に FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper) を追加してから、アセンブリ名 (AuthoringTagHelpers) を追加します。 ほとんどの開発者は、"*" ワイルドカード構文を使用するほうを選びます。 ワイルドカード構文を使用することで、FQN のサフィックスとしてワイルドカード文字 "*" を挿入できます。 たとえば、以下のディレクティブのいずれかで EmailTagHelper を取り込みます。

@addTagHelper AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers

前述のとおり、@addTagHelper ディレクティブを Views/_ViewImports.cshtml ファイルに追加すると、タグ ヘルパーを Views ディレクトリとサブディレクトリ内のすべてのビュー ファイルで使用できるようになります。 これらのビューにのみタグ ヘルパーを公開することを選択する場合は、特定のビュー ファイルで @addTagHelper ディレクティブを使用できます。

@removeTagHelper でタグ ヘルパーを削除する

@removeTagHelper には @addTagHelper と同じ 2 つのパラメーターがあり、以前に追加されたタグ ヘルパーを削除します。 たとえば、特定のビューに適用された @removeTagHelper では、指定されたタグ ヘルパーをビューから削除します。 Views/Folder/_ViewImports.cshtml ファイルで @removeTagHelper を使用すると、Folder 内のすべてのビューから指定されたタグ ヘルパーが削除されます。

_ViewImports.cshtml ファイルによるタグ ヘルパー スコープの制御

_ViewImports.cshtml を任意のビュー フォルダーに追加することができ、ビュー エンジンではそのファイルと Views/_ViewImports.cshtml ファイルの両方のディレクティブが適用されます。 空の Views/Home/_ViewImports.cshtml ファイルを Home ビューに追加する場合、 _ViewImports.cshtml ファイルは付加的であるため、変更は生じません。 Views/Home/_ViewImports.cshtml ファイルに追加する @addTagHelper ディレクティブ (既定の Views/_ViewImports.cshtml ファイルにはない) では、これらのタグ ヘルパーが Home フォルダー内のビューにのみ公開されます。

個々の要素の無効化

タグ ヘルパーのオプトアウト文字 ("!") を使用して、要素レベルでタグ ヘルパーを無効にすることができます。 たとえば、Email 検証は、タグ ヘルパーのオプトアウト文字を使用して <span> で無効にすることができます。

<!span asp-validation-for="Email" class="text-danger"></!span>

開始タグと終了タグにタグ ヘルパーのオプトアウト文字を適用する必要があります (Visual Studio エディターでは、ユーザーがオプトアウト文字を開始タグに追加すると、自動的にオプトアウト文字が終了タグに追加されます)。 オプトアウト文字を追加した後、要素とタグ ヘルパーの属性は独特なフォントで表示されなくなります。

@tagHelperPrefix を使用してタグ ヘルパーの使用状況を明確にする

@tagHelperPrefix ディレクティブでは、タグ プレフィックス文字列を指定して、タグ ヘルパーのサポートを有効にしたり、タグ ヘルパーの使用状況を明確にすることができます。 たとえば、Views/_ViewImports.cshtml ファイルに次のマークアップを追加できます。

@tagHelperPrefix th:

以下のコード イメージでは、タグ ヘルパーのプレフィックスが th: に設定されているため、プレフィックス th: を使用する要素のみでタグ ヘルパーがサポートされます (タグ ヘルパーが有効な要素には独特なフォントがあります)。 <label> 要素と <input> 要素にはタグ ヘルパー プレフィックスがあり、タグ ヘルパーが有効ですが、<span> 要素にはありません。

ラベルと入力要素名のタグ ヘルパーのプレフィックスが "th:" に設定された Razor マークアップ

@addTagHelper に適用されるものと同じ階層規則が @tagHelperPrefix にも適用されます。

自己終了タグ ヘルパー

多くのタグ ヘルパーは、自己終了タグとして使用できません。 一部のタグ ヘルパーは、自己終了タグとして設計されています。 自己終了するようになっていないタグ ヘルパーを使用すると、表示される出力が抑制されます。 タグ ヘルパーを自己終了すると、表示される出力の中に自己終了タグが配置されます。 詳細については、タグ ヘルパーの作成に関するページのこちらの注意をご覧ください。

タグ ヘルパーの属性/宣言内の C#

タグ ヘルパーでは要素の属性またはタグ宣言区分の C# は許可されません。 たとえば、次のようなコードは有効ではありません。

<input asp-for="LastName"  
       @(Model?.LicenseId == null ? "disabled" : string.Empty) />

上記のコードは、次のように記述できます。

<input asp-for="LastName" 
       disabled="@(Model?.LicenseId == null)" />

Intellisense でのタグ ヘルパーのサポート

Visual Studio で新しい ASP.NET Core Web アプリを作成するときに、NuGet パッケージ "Microsoft.AspNetCore.Razor.Tools" が追加されます。 これは、タグ ヘルパー ツールを追加するパッケージです。

HTML <label> 要素を書き込むことを検討してください。 Visual Studio エディターで <l を入力するとすぐに、IntelliSense で一致する要素が表示されます。

キーボードで「l」を入力すると、IntelliSense により "label" が選択された使用可能なタグ名の候補の一覧が表示されます。

HTML ヘルプだけでなく、アイコン ("@" symbol with "<>") も表示されます。

下に "<>" が付いた @" symbol with " 記号。

このアイコンは、タグ ヘルパーのターゲットとなる要素を示します。 純粋な HTML 要素 (fieldset など) では "<>" アイコンが表示されます。

純粋な HTML <label> タグの場合、HTML タグ (既定の Visual Studio の配色テーマ) が茶色のフォントで、属性が赤で、属性値が青で表示されます。

"label" HTML タグの例

<label を入力した後、IntelliSense では次のように使用可能な HTML/CSS 属性とタグ ヘルパーのターゲットとなる属性がリストされます。

ユーザーが左角かっこと HTML 要素名「label」を入力しました。 IntelliSense により、使用可能な属性の一覧が表示されます (事前には選択されていません)。

IntelliSense ステートメント入力候補では、Tab キーを入力して、選択した値を使用してステートメントを完了することができます。

ユーザーは、左角かっこ、HTML 要素名「label」を入力し、属性名 ("as") の入力を開始しました。 IntelliSense により、"asp-for" が選択された状態で、候補のダイアログが表示されます。

タグ ヘルパー属性が入力されるとすぐに、タグと属性のフォントが変わります。 既定の Visual Studio の "青" または "ライト" の配色テーマを使用すると、フォントが太字の紫になります。 "ダーク" テーマを使用する場合、フォントは太字の青緑になります。 このドキュメントのイメージは、既定のテーマを使用して取得されたものです。

ユーザーが "asp-for" を選択しましたが、ユーザーがダークテーマを使用していないため、紫色の太字になっています。

Visual Studio の CompleteWord ショートカット (既定は Ctrl + Space) を二重引用符 ("") 内に入力することができ、C# クラスの場合と同じように C# で使用できるようになりました。 IntelliSense では、ページ モデルですべてのメソッドとプロパティが表示されます。 プロパティの種類が ModelExpression であるため、メソッドとプロパティを使用できます。 次のイメージでは、Register ビューを編集するため、RegisterViewModel を使用できます。

ユーザーは、"asp-for" 属性の値に「e」を入力します。 IntelliSense により、"Email" が選択された状態で使用できる入力候補が示されます。

IntelliSense では、ページのモデルで使用可能なプロパティとメソッドがリストされます。 豊富な IntelliSense 環境は、CSS クラスを選択する場合に役立ちます。

ユーザーは「cl」を入力して、"input" 要素に属性を追加します。 IntelliSense により、"class" が選択された状態で入力候補の提案の一覧が示されます。

ユーザーは、"input" 要素の "class" 属性の値として「co」と入力します。 IntelliSense により、"col" が選択された状態で使用できる入力候補の一覧が提供されます。

タグ ヘルパーと HTML ヘルパーの比較

タグ ヘルパーは Razor ビューで HTML 要素にアタッチされますが、HTML ヘルパーは Razor ビューで HTML に点在するメソッドとして呼び出されます。 たとえば、CSS クラス "caption" を指定して HTML ラベルを作成する、次のような Razor マークアップがあるとします。

@Html.Label("FirstName", "First Name:", new {@class="caption"})

アットマーク (@) 記号は、Razor で、それコードの先頭であることを示します。 次の 2 つのパラメーター ("FirstName" と "First Name:") は文字列であるため、IntelliSense では対応できません。 以下が最後の引数です。

new {@class="caption"}

これは属性を表すために使用される匿名オブジェクトです。 class は C# の予約済みのキーワードであるため、@ シンボルを使用して、C# で強制的に @class= をシンボル (プロパティ名) として解釈するようにします。 フロント エンドのデザイナー (HTML/CSS/JavaScript とその他のクライアント テクノロジを熟知しているが、C# や Razor は使い慣れていない方) には、ほとんどの行が見慣れないものでしょう。 IntelliSense に頼らずに行全体を作成する必要があります。

LabelTagHelper を使用すれば、以下と同じマークアップを書き込むことができます。

<label class="caption" asp-for="FirstName"></label>

タグ ヘルパー バージョンを使用して Visual Studio エディターで <l を入力するとすぐに、IntelliSense で一致する要素が表示されます。

ユーザーがキーボードに「l」と入力します。 IntelliSense により、"label" が選択された状態で、HTML 要素の候補が示されます。

IntelliSense は行全体を書き込む場合に役立ちます。

次のコードの画像は、Visual Studio に含まれている ASP.NET 4.5.x MVC テンプレートから生成される Views/Account/Register.cshtml Razor ビューの Form 部分を示しています。

ASP.NET 4.5 MVC プロジェクト テンプレートの Register Razor ビューのフォーム部分のRazor マークアップ

Visual Studio エディターでは、背景が灰色の C# コードが表示されます。 たとえば、次の AntiForgeryToken HTML ヘルパーの場合、

@Html.AntiForgeryToken()

灰色の背景で表示されます。 Register ビューのマークアップのほとんどは C# です。 以下のタグ ヘルパーを使用する同じ方法と比較します。

ASP.NET Core プロジェクト テンプレートの Register Razor ビューのフォーム部分にタグ ヘルパーを使用した Razor マークアップ

HTML ヘルパーの方法よりも、マークアップがわかりやすく、読み取り、編集、保持が簡単になります。 C# コードは、サーバーで認識する必要がある最低限まで減っています。 Visual Studio エディターでは、独特なフォントでタグ ヘルパーのターゲットとなるマークアップが表示されます。

たとえば、以下の Email グループについて考えてみます。

<div class="form-group">
    <label asp-for="Email" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
</div>

"asp-" 属性にはそれぞれ "Email" の値がありますが、"Email" は文字列ではありません。 このコンテキストでは、"Email" は RegisterViewModel の C# モデル式のプロパティとなります。

Visual Studio エディターは登録フォームのタグ ヘルパーの方法で すべて のマークアップを書き込む場合に役立ちますが、Visual Studio は HTML ヘルパーの方法ではほとんどのコードに対応できません。 Visual Studio エディターでのタグ ヘルパーの操作の詳細については、「IntelliSense でのタグ ヘルパーのサポート」を参照してください。

タグ ヘルパーと Web サーバー コントロールの比較

  • タグ ヘルパーには関連付けられている要素はなく、要素とコンテンツのレンダリングに参加するだけです。 ASP.NET Web サーバー コントロールはページで宣言され、呼び出されます。

  • ASP.NET Web サーバー コントロールには複雑なライフサイクルがあり、これが開発とデバッグを困難にする場合があります。

  • Web サーバー コントロールではクライアント コントロールを使用して、クライアントのドキュメント オブジェクト モデル (DOM) 要素に機能を追加することができます。 タグ ヘルパーには DOM がありません。

  • Web サーバー コントロールには自動ブラウザー検出が含まれます。 タグ ヘルパーではブラウザーが認識されません。

  • 複数のタグ ヘルパーを同じ要素で実行できますが (タグ ヘルパーの競合の回避に関するページを参照)、通常は Web サーバー コントロールを構成できません。

  • タグ ヘルパーではスコープとなる HTML 要素のタグとコンテンツを変更できますが、ページ上の他のものを直接変更しません。 Web サーバー コントロールではスコープが限定されないため、ページの他の部分に影響を与えるアクションを実行して、予想外の結果となる場合があります。

  • Web サーバー コントロールでは型コンバーターを使用して、文字列をオブジェクトに変換します。 タグ ヘルパーの場合、C# でネイティブに作業するため、型を変換する必要はありません。

  • Web サーバー コントロールでは System.ComponentModel 名前空間を使用して、コンポーネントやコントロールの実行時動作およびデザイン時動作を実装します。 System.ComponentModel には、属性と型コンバーターの実装、データ ソースへのバインド、コンポーネントのライセンス処理のための基底クラスと基底インターフェイスが含まれています。 通常は TagHelper から派生するタグ ヘルパーとは異なり、TagHelper 基底クラスでは ProcessProcessAsync の 2 つのメソッドのみを公開します。

タグ ヘルパー要素のフォントのカスタマイズ

次のように、 [ツール] > [オプション] > [環境] > [フォントおよび色] からフォントと色づけをカスタマイズすることができます。

Visual Studio の [オプション] ダイアログ

組み込み ASP.NET Core タグ ヘルパー

アンカー タグ ヘルパー

キャッシュ タグ ヘルパー

コンポーネント タグ ヘルパー

分散キャッシュ タグ ヘルパー

環境タグ ヘルパー

フォーム タグ ヘルパー

フォーム アクション タグ ヘルパー

イメージ タグ ヘルパー

入力タグ ヘルパー

ラベル タグ ヘルパー

リンク タグ ヘルパー

部分タグ ヘルパー

スクリプト タグ ヘルパー

選択タグ ヘルパー

Textarea タグ ヘルパー

検証メッセージ タグ ヘルパー

検証概要タグ ヘルパー

その他の技術情報