tmytのらくがき

個人の日記レベルです

ASP.NET CoreのTagHelperでいろいろするメモ

TagHelper

TagHelperを継承したクラスで、ProcessAsyncをoverrideしていろいろすると、出力をいろいろできる。

いろいろする

// ターゲットにするタグ名をここに付ける
[HtmlTargetElement("my:Example")] 
public class ExampleTagHelper : TagHelper
{
  // ViewContextオブジェクトを格納してほしい時に書く。
  // これがあると、TagHelperの内側からHttpContextとかにアクセスし放題になる
  [ViewContext]
  // 属性をBindしたくないときに付ける
  [HtmlAttributeNotBound]
  public ViewContext ViewContext { get; set; }

  // プロパティにバインドしたい属性を書く
  [HtmlAttributeName("hello")] 
  public string Hello { get; set; } = "";

  // これをoverrideしていろいろする
  public override Task ProcessAsync(
    // Bindした属性のリストとかはこっち
    TagHelperContext context,
    // Bindしてない属性のリストとか、出力するタグの設定とかはこっち
    TagHelperOutput output)
  {
    // 子要素のHTML-string はこれで読める
    var content = (await output.GetChildContentAsync()).GetContent();
    // タグを my:Example から div に変える
    output.TagName = "div";
    // 自己終了タグとして使いたいTagHelperなのに出力されるHTMLが自己終了だと都合が悪い時などにTagModeを変える
    // output.TagMode = TagMode.StartTagAndEndTag;
    // 属性を好きに付け替えたりできる
    output.Attributes.SetAttribute("style", "color: red");
    // 中身も好き勝手編集できる
    output.PreElement.SetHtmlContent("[1]");
    output.PreContent.SetHtmlContent("[2]");
    output.Content.SetHtmlContent($"[3] {Hello}");
    output.PostContent.SetHtmlContent("[4]");
    output.PostElement.SetHtmlContent("[5]");
    return Task.CompletedTask;
  }
}

このTagHelperをRazorからこんな感じで呼ぶ

<my:Example hello="world" />

そうすると、こう出力される。

[1]
<div>
[2]
[3] world
[4]
</div>
[5]

便利。