コンテンツへスキップ
ASP. NET Core – カスタム タグ ヘルパーの作成

ASP. NET Core – カスタム タグ ヘルパーの作成

Asp.net Core は、TagHelpers を使用してカスタムタグでRazor構文を拡張する方法を提供します。

5min read

ASP.NET Coreでは、TagHelpers を使用してカスタムタグでRazor構文を拡張する方法を提供します。TagHelpersを使用すると、htmlの外観により、C#以外の人からRazorビューがはるかに理解しやすくなります。ラベルの作成にHTMLヘルパーを使用する代わりに、TagHelperを使用できるようになりました。

たとえば、ユーザー名入力のラベルを作成する場合は、次の構文を使用する必要があります。

@Html.Label("Username", "Username:", new { @class = "control-label" })

ラベルに属性を設定するには、3番目のパラメータとして匿名オブジェクトを指定する必要があります。フロントエンド開発者やC#以外の人にとっては、この構文はなじみがなく、クラスを変更したり、クラスや属性を追加したりするには、C#の知識が必要です。

LabelTagHelper を使用しても同じことを実現できます。

<ig-loader css-path="http://localhost/css"
           javascript-path="http://localhost/css"
           resources="combo"/>

上の行は、C# コードではなくマークアップ宣言であるため、はるかに理解しやすく、HTML に適しています。

TagHelpers を使用しているため、Visual Studio IntelliSence のサポートを利用できます。

TagHelpers を使用しているため、Visual Studio IntelliSence のサポートを利用できます

これは非常に素晴らしいように見えますが、カスタムTagHelpersを作成するのはどうですか?

答えは「はい」です、これは可能であり、グリッドやドロップダウンなどの複雑なコントロールを作成できます。

カスタムTagHelperを作成するために必要なのは、TagHelperクラスを継承することだけです(ここにハイパーリンクを挿入)。

JavaScriptやCSSなどのリソースをロードするLoaderというTagHelperを作成しましょう。ローダーはIgnite UI AMDコンポーネントです。

Visual Studio のテンプレートは、[新しい項目の追加] メニューから使用できます。

[新しい項目の追加] メニューから Visual Studio のテンプレートを使用する

そして、次のクラスが作成されます。

using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WebApplication1.TagHelpers {
    // You may need to install the Microsoft.AspNetCore.Razor.Runtime package into your project
    [HtmlTargetElement("tag-name")]
    public class LoaderTagHelper: TagHelper {
        public override void Process(TagHelperContext context, TagHelperOutput output) {}
    }
}

LoaderTagHelper は、次の構造を持ちます

<ig-loader css-path="http://localhost/css"
           javascript-path="http://localhost/css"
           resources="combo" />

以下は、htmlを含むスクリプトタグとしてレンダリングされます。

HtmlTargetElement の値を "ig-loader" に変更することで、TagHelper を ig-loader にマッピングする必要があります。TagHelper 属性は C# プロパティにマップする必要があり、これを実現するために HtmlAttributeName を使用して、タグ ヘルパー属性の名前を値として指定します。

クラスは次のようになります。

using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WebApplication1.TagHelpers {
    [HtmlTargetElement("ig-loader")]
    public class LoaderTagHelper: TagHelper {
        [HtmlAttributeName("css-path")]
        public string CssPath {
            get;
            set;
        }
        [HtmlAttributeName("javascript-path")]
        public string JavaScriptPath {
            get;
            set;
        }
        [HtmlAttributeName("resources")]
        public string Resources {
            get;
            set;
        }
        public override void Process(TagHelperContext context, TagHelperOutput output) {}
    }
}

TagHelper をレンダリングして html を出力するには、Process メソッドを使用します。出力を設定します。TagName を空の文字列にし、html を出力コンテンツに追加します。

public override void Process(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = string.Empty;
    output.Content.AppendHtml($" ");
}

これは素晴らしいことですが、それらの間の関係を持つより複雑なTagHelperを作成するにはどうすればよいでしょうか?

TagHelperContext.Itemsディクショナリを使用して、その子TagHelperと通信し、リレーションを作成できます。

複数選択機能を持つComboTagHelperを作成しましょう。

次の構造を与えています。

<ig-combo ig-data-source="@Model" ig-key="Id" ig-value="Name">
    <ig-combo-multi-selection ig-is-enabled="true" ig-enable-checkboxes="true" />
</ig-combo>

相対的に次の C# クラスがあります。

using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WebApplication1.TagHelpers {
    [HtmlTargetElement("ig-combo")]
    public class ComboTagHelper: TagHelper {
        [HtmlAttributeName("ig-key")]
        public string Key {
            get;
            set;
        }
        [HtmlAttributeName("ig-value")]
        public string Value {
            get;
            set;
        }
        [HtmlAttributeName("ig-data-source")]
        public object DataSource {
            get;
            set;
        }
        public MultiSelectionTagHelper MultiSelection {
            get;
            set;
        }
        public override void Process(TagHelperContext context, TagHelperOutput output) {}
    }
}

そして

using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WebApplication1.TagHelpers {
    [HtmlTargetElement("ig-combo-multi-selection")]
    public class MultiSelectionTagHelper: TagHelper {
        [HtmlAttributeName("ig-enable-checkboxes")]
        public bool EnableCheckBoxes {
            get;
            set;
        }
        [HtmlAttributeName("ig-is-enabled")]
        public bool Enabled {
            get;
            set;
        }
        public override void Process(TagHelperContext context, TagHelperOutput output) {}
    }
}

TagHelpers間のリレーションを作成し、正しいコンテキストで親のMultiSelectionプロパティを初期化するために、そのコンテキストのitemsコレクションに親のインスタンスを渡します。

親プロセスメソッドでは、これをキーComboTagHelperに渡し、子コンテキストを取得して、その属性を解析できるようにします。

public async override void Process(TagHelperContext context, TagHelperOutput output)
{
    context.Items.Add(typeof(ComboTagHelper), this);
    await output.GetChildContentAsync();
    // Set the output of the TagHelper
}

子プロセスでは、親のMultiSelectionプロパティへの参照を設定し、出力を抑制します。

public override void Process(TagHelperContext context, TagHelperOutput output)
{
    ((ComboTagHelper)context.Items[typeof(ComboTagHelper)]).MultiSelectionSettings = this;
    output.SuppressOutput();
}

これで、子のTagHelperが親のプロパティとして処理され、それを使用して出力をレンダリングできます。

TagHelpers は、Ignite UIのボリュームリリース 16.2 で使用できます。

デモを予約