Tag Helper
Eintrag zuletzt aktualisiert am: 12.09.2019
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 Model-View-Controller –
MVC) oder in Pages (bei
ASP.NET Core Razor Pages) einsetzen.
Dies ist vergleichbar mit den
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
Webforms, sind aber in ihrer Implementierung wesentlich einfacher. Eine Entwurfszeitansicht gibt es hier nicht. Tag Helpers können sich auch auf Standard-HTML-Tags beziehen und diese modifizieren.
Vordefinierte Tag Helper
Microsoft liefert bereites eine Reihe eigener Tags, z.B.
- <partial>
- <cache> und
- <environment>
sowie Tag-
Attribute (die mit der Vorsilbe "asp-" beginnen), z.B.
- asp-controller und asp-action for <form>
- asp-for für <label>, <input> und <select>
- asp-append-version für <img>
- asp-validation-for für <span>
in
ASP.NET Core in der Microsoft.AspNetCore.Mvc.TagHelpers.dll mit.
Damit diese Tag Helper überhaupt nutzbar sind, müssen Sie mit @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers eingebunden werden. Dies erledigt Microsoft freundlicherweise in den Projektvorlage "Web Application" und "Web Application (
MVC)" schon in der Datei /Shared/_ViewImports.cshtml, die automatisch für jeden View geladen wird.
Listing 1 zeigt Tags mit "asp-" beginnenden Erweiterungsattributen (asp-for, asp-append-version, usw). Microsoft nennt diese Erweiterungsattribute sowie eigenständigen neue Tags wie <environment> und <cache> in Listing 1 "Tag Helper". Sie sind eine elegante Alternative zu den bisherigen
HTML Helper-Funktionen (z.B. @Html.
TextBoxFor()), die es aber auch weiterhin gibt. Im Einzelnen bieten die in Listing 1 verwendeten Tag Helper folgende Funktionen:
- asp-for: Datenbindung an ein Property aus dem Modell
- asp-append-version: Anhängen eines Hash-Wertes für die Datei, der sich jedes Mal ändert, wenn sich die Datei ändert. So wird verhindert, dass der Benutzer wegen Caching im Browser nicht die aktuelle Datei sieht (Cache Busting).
- <cache>: Zwischenspeicherung des Inhalts für die bei expires-after angegebene Zeitdauer.
- <environment>: Ausgabe nur, wenn einer der Names genannten Umgebungen aktiv ist. Den Namen für die aktive Umgebung legt man in der Umgebungsvariablen ASPNETCOREENVIRONMENT fest. Mit diesem Tag Helper definiert Microsoft in der Standardlayoutvorlage in der Datei /Shared/Layout.html, dass in den Umgebungen "Staging" und "Produktion", die Bootstrap-CSS-Datei im Standard aus dem Content Delivery Network (CDN) von Microsoft kommt.
Es gibt weitere eingebaute Tag Helper in der
Komponente Microsoft.AspNetCore.Mvc.TagHelpers.dll. Damit die Tag Helper überhaupt nutzbar sind, müssen Sie mit @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers eingebunden werden. Dies erledigt Microsoft freundlicherweise in der Projektvorlage schon in der Datei /Shared/_ViewImports.cshtml, die automatisch für jeden View geladen wird.
Listing 1: Eingebaute Tag Helper
@model ITVisions.Autor
<html>
<h3>Autor #@Model.ID: @Model.Name</h3>
<img width="50" src="~/images/Foto_@(Model.Name.Replace(" ","")+".jpg")" asp-append-version="true" />
<input asp-for="Name" class="form-control" />
...
<div>
<cache expires-after="@TimeSpan.FromMinutes(10)">
Zuletzt aktualisiert @DateTime.Now.ToString().
</cache>
Dies ist die
<environment names="development">
Entwicklungsumgebung!</environment>
<environment names="test1,test2">Testumgebung!</environment>
<environment names="produktion">Produktionsumgebung!</environment>
</div>
</html>
Eigene Tag Helper
Natürlich kann der Softwareentwickler eigene Tag Helper schreiben. Dazu erstellt er eine öffentliche Klasse, die von Microsoft.AspNetCore.
Razor.TagHelpers.TagHelper erbt. Der Name der Klasse sollte konventionsgemäß auf TagHelper enden. Der vordere Teil wird dann zum Tagnamen, wobei Kebab
Casing (alias Spinal
Casing) Anwendung findet, d.h.
- Aus der Klasse AutorTagHelper entsteht das Tag <autor>
- Aus der Klasse DateTimeTagHelper entsteht das Tag <date-time/>
Wenn man einen anderen Tagnamen wünscht oder nicht ein eigenständiges Tag, sondern nur ein neues
Attribut für ein bestehendes Tag definieren will, muss man die
Annotation [HtmlTargetElement] verwenden.
Eine Tag Helper-Klasse kann öffentliche Properties anbieten, die zu Tag-
Attributen werden. Die Klasse überschreibt entweder die
Methoden Process() oder ProcessAsync(). Diese
Methoden erhalten im
Methodenparameter über ein TagHelperContext-
Objekt den aktuellen Elementnamen und Taginhalt; sie geben über das ebenfalls per Parameter übergebene
Objekt TagHelperOutput den aktualisierten Inhalt zurück.
Die
Methodensignatur ist also entweder:
public override void Process(TagHelperContext context, TagHelperOutput output)
{
}
oder:
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
}
Die asynchrone Variante ist aus Gründen der besseren skalierbarkeit zu beveorzugen.
Einbindung der eigenen Tag Helper
Voraussetzung für das Funktionieren aller hier dargestellten Tag Helper ist, dass die Tag Helper mit @addTagHelper einbindet. Wenn die Tag Helper in dem Namensraum ITVisions und in der
DLL-
Assembly ITVTagHelper liegen, muss die Einbindung so erfolgen:
@addTagHelper "ITVisions.AutorTagHelper, ITVTagHelper" eingebunden
- Alle Tag Helper in einem Namensraum
@addTagHelper "ITVisions*, ITVTagHelper"
@addTagHelper "*, ITVTagHelper"
Beispiel
Listing 2 zeigt das Beispiel des Tag Helpers <Autor>, das ein Autor-
Objekt und eine Zahl (Size) als
Attribute besitzt und daraus eine Ausgabe in einem HTML-Header-Tag (<h1>, <h2>, <h3> usw.) erzeugt.
Somit kann man 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 Klassennamen und der zweite Parameter der
Assemblyname ist. Anstelle des Klassennamens kann man auch mit * alle Tag Helper einer
Assembly einbinden.
Listing 2: Implementierung eines Tag Helpers für das eigene Tag <Autor>
using System;
using WindowsDeveloper;
using Microsoft.AspNetCore.
Razor.TagHelpers;
namespace ITVisions
{
/// <summary>
/// Tag Helper <Autor autor="objekt" size="zahl 1 bis 5"></Autor>
/// </summary>
public class AutorTagHelper : 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;
}
}
}