ASP.NET Core のタグ ヘルパー コンポーネント
作成者: Scott Addie、Fiyaz Bin Hasan
タグ ヘルパー コンポーネントは、サーバー側のコードから HTML 要素を、条件に応じて変更または追加できるタグ ヘルパーです。 この機能は、ASP.NET Core 2.0 以降で使用できます。
ASP.NET Core には、組み込みのタグ ヘルパー コンポーネントが 2 つ (head
と body
) 含まれています。 これらは Microsoft.AspNetCore.Mvc.Razor.TagHelpers 名前空間に配置され、MVC と Razor Pages の両方で使用できます。 タグ ヘルパー コンポーネントには、_ViewImports.cshtml
でのアプリへの登録は必要ありません。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
ユース ケース
タグ ヘルパー コンポーネントの 2 つの一般的なユース ケースは、次のとおりです。
次のセクションでは、これらのユース ケースについて説明します。
HTML の head 要素の挿入
HTML <head>
要素内で、CSS ファイルは HTML <link>
要素でよくインポートされます。 次のコードでは、head
タグ ヘルパー コンポーネントを使用して <link>
要素が <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 要素に挿入
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);
}
}
}
}
個別の HTML ファイルを使用して、<script>
要素を格納します。 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>
上のコードでは、ブートストラップ ヒント ウィジェットを printable
属性を含む任意の <address>
要素にバインドします。 要素の上にマウス ポインターが移動したときに、効果が表示されます。
コンポーネントの登録
タグ ヘルパー コンポーネントは、アプリのタグ ヘルパー コンポーネント コレクションに追加する必要があります。 コレクションに追加するには、次の 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 Pages ページまたは 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
のインスタンスが提供されます。 インスタンスは、Razor ファイルでダウンストリームのアクセスを行うために、manager
という名前の変数に割り当てられます。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 コントローラーから登録できます。 この技法は、Razor ファイルから C# ロジックを分離するのに便利です。
コンストラクター挿入を使用して、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 要素の名前を指定します。 - 省略可能: IntelliSense で型を表示しないようにするには、
[EditorBrowsable(EditorBrowsableState.Never)]
属性をクラスに適用します。
次のコードでは、<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
属性がある場合。
たとえば、次の <address>
要素を処理しているときに、if
ステートメントの評価の結果が true になります。
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
その他のリソース
ASP.NET Core
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示