Tag Helper sind Tags oder Attribute für Tags in Razor Templates, die von ASP.NET Core auf der Serverseite vor der Auslieferung der Website durch andere Tags oder Eigenschaften ersetzt werden. Tag Helper kann ein Webentwickler in Views (bei ASP.NET Core MVC) oder in Pages (bei ASP.NET Core Razor Pages) einsetzen.
Das ist vergleichbar mit Direktiven in Angular, allerdings übersetzt Angular die Direktiven clientseitig (also erst im Browser) in Standard-HTML-Tags. Tag Helper nehmen eine ähnliche Rolle ein wie früher die Webserversteuerelemente in ASP.NET Web Forms, sind aber in ihrer Implementierung wesentlich einfacher. Eine Entwurfszeitansicht gibt es hier nicht. Tag Helper können sich auch auf Standard-HTML-Tags beziehen und sie modifizieren.
Listing 1 zeigt das Beispiel des Tag Helpers <Autor>, das ein Autorobjekt und eine Zahl (Size) als Attribute besitzt und daraus eine Ausgabe in einem HTML-Header-Tag (<h1>, <h2>, <h3> usw.) erzeugt.
Listing 1: Implementierung eines Tag Helpers für den eigenen Tag <Autor>
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace ITVisions
{
/// <summary>
/// Tag Helper
/// Verwendung: <Autor autor="objekt" size="zahl /// 1 bis 5"></Autor>
/// </summary>
public class AutorTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper
{
/// <summary>
/// Komplexes Objekt als Parameter
/// </summary>
public Autor Autor { get; set; }
/// <summary>
/// Zahl als Parameter
/// </summary>
public byte Size { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (Size > 5) Size = 5;
output.TagName = "h" + Size.ToString();
output.Content.SetContent(
$@"Autor #{Autor.ID}: {Autor.Name}");
output.TagMode = TagMode.StartTagAndEndTag;
}
}
}
Man kann nun mit dem neuen Tag Helper anstelle von <h3>Autor #@Model.ID: @Model.Name</h3> die gekapselte Form verwenden: <Autor size="3" autor="Model"></Autor>, sofern man vorher das Tag mit @addTagHelper "ITVisions.AutorTagHelper, ITVTagHelper" eingebunden hat, wobei der erste Parameter der Klassenname und der zweite Parameter der Assembly-Name ist. Anstelle des Klassennamens kann man auch mit * alle Tag Helper einer Assembly einbinden.
Mit Tag Helpern kann man das Repeater-Steuerelement aus ASP.NET Web Forms nachbauen. Der Trick ist, dass man ProcessAsync() verwendet, dass erlaubt, beliebige Inhalte im Tag mit GetChildContentAsync() wieder zu rendern. Auch Tag Helper können wieder im Inhalt enthalten sein (Listing 2).
Listing 2: Tag Helper <repeater>
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;
namespace ITVisions
{
/// <summary>
/// x Wiederholungen des Kindinhaltes
/// </summary>
public class RepeaterTagHelper : TagHelper
{
public int Count { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = null;
for (int i = 0; i <= Count; i++)
{
var e = await output.GetChildContentAsync(useCachedResult: false);
output.Content.AppendHtml(e.GetContent());
}
}
}
}
Beim Beispiel in Listing 3 kommen zwei Tag-Helper-Attribute fett und kursiv zum Einsatz. Den Einsatz eines Tag Helpers mit untergeordneten Tag Helpern zeigt Listing 4. Die geraden Jahre werden fett dargestellt, die ungeraden kursiv.
Listing 3: Tag-Helper-Attribute für fett und kursiv
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace ITVisions
{
[HtmlTargetElement(Attributes = "fett")]
public class FettTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.RemoveAll("fett");
output.Attributes.Add("style","font-weight:bold");
//oder:
//output.PreContent.SetHtmlContent(“<strong>”);
//output.PostContent.SetHtmlContent(“</strong>”);
}
}
[HtmlTargetElement(Attributes = "kursiv")]
public class Italic : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.Attributes.RemoveAll("kursiv");
output.Attributes.Add("style", "font-style:italic");
//oder:
//output.PreContent.SetHtmlContent(“<i>”);
//output.PostContent.SetHtmlContent(“</i>”);
}
}
}
Listing 4: Einsatz von <repeater>
<p>Repeater:</p>
@{
int jahr = DateTime.Now.Year;
}
<ul>
<repeater count="5">
@if (jahr % 2 == 0)
{
<li fett>Jahr @(jahr++) </li>
}
else
{
<li kursiv>Jahr @(jahr++) </li>
}
</repeater>
</ul>
Der Tag Helper in Listing 5 zeigt, wie man Inhalte beim Rendern via SuppressOutput() leicht mit einem eigenen Tag-Helper-Attribut unterdrückt, das man in jedes beliebige Attribut einbauen kann. Alle Tag-Helper-Parameter, die nicht vom Typ string sind, werden beim Aufruf als Ausdrücke behandelt – auch ohne Razor-Syntax mit @!.
Listing 5: Tag-Helper-Attribut Condition
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace ITVisions
{
[HtmlTargetElement(Attributes = nameof(Condition))]
public class ConditionTagHelper : TagHelper
{
public bool Condition { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (!Condition)
{
output.SuppressOutput();
}
}
}
}
Dr. Holger Schwichtenberg (MVP) – alias „Der DOTNET-DOKTOR“ – gehört zu den bekanntesten .NET-Experten in Deutschland. Er ist Entwicklungsleiter der 5Minds IT-Solutions GmbH & Co. KG. Zudem unterstützt er mit seiner Firma www.IT-Visions.de kleine und große Unternehmen durch Beratung und Schulung bei der Erstellung von Windows- und webbasierten .NET-Anwendungen. Seit 1998 ist er ununterbrochen Sprecher auf jeder BASTA und Autor zahlreicher Fachbücher.