タグ ヘルパー コンポーネントは、サーバー側コードから HTML 要素を条件付きで変更または追加できるタグ ヘルパーです。 この機能は、ASP.NET Core 2.0 以降で使用できます。
ASP.NET Core には、 head
と body
の 2 つの組み込みのタグ ヘルパー コンポーネントが含まれています。 これらは Microsoft.AspNetCore.Mvc.Razor.TagHelpers 名前空間にあり、MVC と Razor Pages の両方で使用できます。 タグ ヘルパー コンポーネントでは、 _ViewImports.cshtml
でアプリに登録する必要はありません。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
活用事例
タグ ヘルパー コンポーネントの一般的なユース ケースには、次の 2 つがあります。
以降のセクションでは、これらのユース ケースについて説明します。
HTML ヘッド要素に挿入する
HTML <head>
要素内では、CSS ファイルは一般的に HTML <link>
要素と共にインポートされます。 次のコードでは、<link>
タグ ヘルパー コンポーネントを使用して、<head>
要素を head
要素に挿入します。
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressStyleTagHelperComponent : TagHelperComponent
{
private readonly string _style =
@"<link rel=""stylesheet"" href=""/css/address.css"" />";
public override int Order => 1;
public override Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "head",
StringComparison.OrdinalIgnoreCase))
{
output.PostContent.AppendHtml(_style);
}
return Task.CompletedTask;
}
}
}
前のコードでは、次のようになります。
-
AddressStyleTagHelperComponent
は、TagHelperComponent を実装します。 抽象化:- TagHelperContextを使用したクラスの初期化を許可します。
- タグ ヘルパー コンポーネントを使用して HTML 要素を追加または変更できるようにします。
-
Orderプロパティは、コンポーネントをレンダリングする順序を定義します。
Order
は、アプリでタグ ヘルパー コンポーネントを複数使用する場合に必要です。 -
ProcessAsync は、実行コンテキストの TagName プロパティ値を
head
と比較します。 比較が true と評価された場合、_style
フィールドの内容が HTML<head>
要素に挿入されます。
HTML 本文要素に挿入する
body
タグ ヘルパー コンポーネントは、<script>
要素を <body>
要素に挿入できます。 次のコードは、この手法を示しています。
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressScriptTagHelperComponent : TagHelperComponent
{
public override int Order => 2;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "body",
StringComparison.OrdinalIgnoreCase))
{
var script = await File.ReadAllTextAsync(
"TagHelpers/Templates/AddressToolTipScript.html");
output.PostContent.AppendHtml(script);
}
}
}
}
<script>
要素を格納するには、別の HTML ファイルが使用されます。 HTML ファイルを使用すると、コードがよりクリーンになり、保守が容易になります。 上記のコードは、 TagHelpers/Templates/AddressToolTipScript.html
の内容を読み取り、タグ ヘルパー出力と共に追加します。
AddressToolTipScript.html
ファイルには、次のマークアップが含まれています。
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
上記のコードは、ブートストラップ ツールヒント ウィジェットを、<address>
属性を含む任意のprintable
要素にバインドします。 効果は、マウス ポインターが要素の上に置くと表示されます。
コンポーネントの登録
タグ ヘルパー コンポーネントは、アプリのタグ ヘルパー コンポーネント コレクションに追加する必要があります。 コレクションに追加するには、次の 3 つの方法があります。
サービス コンテナーを使用した登録
タグ ヘルパー コンポーネント クラスが ITagHelperComponentManagerで管理されていない場合は、 依存関係挿入 (DI) システムに登録する必要があります。 次のStartup.ConfigureServices
コードは、AddressStyleTagHelperComponent
でAddressScriptTagHelperComponent
クラスと クラスを登録します。
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<ITagHelperComponent,
AddressScriptTagHelperComponent>();
services.AddTransient<ITagHelperComponent,
AddressStyleTagHelperComponent>();
}
Razor ファイルを使用した登録
タグ ヘルパー コンポーネントが DI に登録されていない場合は、 Razor ページまたは MVC ビューから登録できます。 この手法は、挿入されたマークアップと、 Razor ファイルからのコンポーネントの実行順序を制御するために使用されます。
ITagHelperComponentManager
は、タグ ヘルパー コンポーネントを追加したり、アプリから削除したりするために使用されます。 次のコードは、 AddressTagHelperComponent
を使用したこの手法を示しています。
@using RazorPagesSample.TagHelpers;
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
@inject ITagHelperComponentManager manager;
@{
string markup;
if (Model.IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
manager.Components.Add(new AddressTagHelperComponent(markup, 1));
}
前のコードでは、次のようになります。
-
@inject
ディレクティブは、ITagHelperComponentManager
のインスタンスを提供します。 インスタンスは、manager
ファイル内のダウンストリームにアクセスするために Razor という名前の変数に割り当てられます。 -
AddressTagHelperComponent
のインスタンスがアプリのタグ ヘルパー コンポーネント コレクションに追加されます。
AddressTagHelperComponent
は、 markup
パラメーターと order
パラメーターを受け入れるコンストラクターに対応するように変更されます。
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
指定された markup
パラメーターは、 ProcessAsync
で次のように使用されます。
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
TagHelperContent childContent = await output.GetChildContentAsync();
string content = childContent.GetContent();
output.Content.SetHtmlContent(
$"<div>{content}<br>{_markup}</div>{_printableButton}");
}
}
ページ モデルまたはコントローラーを使用した登録
タグ ヘルパー コンポーネントが DI に登録されていない場合は、 Razor Pages ページ モデルまたは MVC コントローラーから登録できます。 この手法は、C# ロジックを Razor ファイルから分離する場合に役立ちます。
コンストラクターの挿入は、 ITagHelperComponentManager
のインスタンスにアクセスするために使用されます。 タグ ヘルパー コンポーネントがインスタンスのタグ ヘルパー コンポーネント コレクションに追加されます。 次の Razor Pages ページ モデルは、 AddressTagHelperComponent
でこの手法を示しています。
using System;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesSample.TagHelpers;
public class IndexModel : PageModel
{
private readonly ITagHelperComponentManager _tagHelperComponentManager;
public bool IsWeekend
{
get
{
var dayOfWeek = DateTime.Now.DayOfWeek;
return dayOfWeek == DayOfWeek.Saturday ||
dayOfWeek == DayOfWeek.Sunday;
}
}
public IndexModel(ITagHelperComponentManager tagHelperComponentManager)
{
_tagHelperComponentManager = tagHelperComponentManager;
}
public void OnGet()
{
string markup;
if (IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
_tagHelperComponentManager.Components.Add(
new AddressTagHelperComponent(markup, 1));
}
}
前のコードでは、次のようになります。
- コンストラクターの挿入は、
ITagHelperComponentManager
のインスタンスにアクセスするために使用されます。 -
AddressTagHelperComponent
のインスタンスがアプリのタグ ヘルパー コンポーネント コレクションに追加されます。
コンポーネントを作成する
カスタム タグ ヘルパー コンポーネントを作成するには:
- TagHelperComponentTagHelperから派生するパブリック クラスを作成します。
- クラスに
[HtmlTargetElement]
属性を適用します。 ターゲット HTML 要素の名前を指定します。 -
省略可能:
[EditorBrowsable(EditorBrowsableState.Never)]
属性をクラスに適用して、IntelliSense での型の表示を抑制します。
次のコードは、 <address>
HTML 要素を対象とするカスタム タグ ヘルパー コンポーネントを作成します。
using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace RazorPagesSample.TagHelpers
{
[HtmlTargetElement("address")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class AddressTagHelperComponentTagHelper : TagHelperComponentTagHelper
{
public AddressTagHelperComponentTagHelper(
ITagHelperComponentManager componentManager,
ILoggerFactory loggerFactory) : base(componentManager, loggerFactory)
{
}
}
}
カスタム address
タグ ヘルパー コンポーネントを使用して、次のように HTML マークアップを挿入します。
public class AddressTagHelperComponent : TagHelperComponent
{
private readonly string _printableButton =
"<button type='button' class='btn btn-info' onclick=\"window.open(" +
"'https://binged.it/2AXRRYw')\">" +
"<span class='glyphicon glyphicon-road' aria-hidden='true'></span>" +
"</button>";
public override int Order => 3;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
var content = await output.GetChildContentAsync();
output.Content.SetHtmlContent(
$"<div>{content.GetContent()}</div>{_printableButton}");
}
}
}
上記のProcessAsync
メソッドは、提供されたSetHtmlContentのHTMLを一致する<address>
要素に挿入します。 インジェクションは、次の場合に発生します。
- 実行コンテキストの
TagName
プロパティ値は、address
と等しくなります。 - 対応する
<address>
要素には、printable
属性があります。
たとえば、次のif
要素を処理すると、<address>
ステートメントは true に評価されます。
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
その他のリソース
- ASP.NET Core における依存関係の注入
- ASP.NET Core でのビューへの依存関係の挿入
- ASP.NET Core 組み込みタグ ヘルパー
ASP.NET Core