Neues in ASP.NET 5, Teil 1: Tag Helper

Werkzeuge  –  2 Kommentare

Die kommende Version 5.0 von Microsofts Webframework ASP.NET ist eine komplette Neuimplementierung. Neben einfacherer Bedienbarkeit und Plattformunabhängigkeit gibt es einige funktionale Neuerungen für Webentwickler. Im ersten Teil einer Serie über diese Neuerungen geht es um Tag Helper.

Die Version 6.0 des MVC-Framework (Model View Controller) in ASP.NET 5.0 bietet einen neuen Ansatz für wiederverwendbare Komponenten in Form sogenannter Tag Helper (nicht zu verwechseln mit den schon in ASP.NET-MVC-Versionen 1 bis 5 verfügbaren HTML Helpers).

Neues in ASP.NET 5

Softwareentwickler können mit Tag Helpers beliebige eigene Tags definieren, die dann auf der Serverseite vor der Auslieferung der HTML-Seite an den Client durch Standard-HTML-Tags ersetzt werden. Das ist vergleichbar mit den Direktiven in AngularJS; allerdings übersetzt das JavaScript-Framework sie clientseitig (also erst im Browser).

Eigene Tags definieren

Beispielsweise können Entwickler ein selbstdefiniertes Tag <datetime/> in einer MVC View verwenden. Der folgende Code zeigt die Tag-Helper-Klasse, die das neue Tag <datetime> in ein <span>-Tag verwandelt, das aktuelles Datum und aktuelle Uhrzeit enthält.

using System;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;

namespace ASPNET5Web
{
public class DatetimeTagHelper : TagHelper
{
public override void Process(TagHelperContext context,
TagHelperOutput output)
{
output.TagName = "span";
output.Content = DateTime.Now.ToString();
}
}
}

Die Implementierung einer solchen Klasse ist einfach. Man schreibt eine öffentliche Klasse, die am Anfang dem Namen des selbstdefinierten Tags entspricht und auf die Wortkombination "TagHelper" endet. Alternativ können Entwickler die Annotation [HtmlElementName("Tagname")] verwenden, wenn sich die Namenskonvention nicht erfüllt werden kann oder soll. Diese Klasse muss von der Basisklasse Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelper ableiten und überschreibt die Methode Process() oder ProcessAsync(). Über den ersten Parameter (context) erhalten Entwickler Zugriff auf die Attribute des eigenen Tags. Über den zweiten (output) legen sie die Ausgabe fest.

ASP.NET 5 ist modular aufgebaut, und Tag Helper sind eine Zusatzkomponente, die von NuGet.org (Milestone-Versionen) beziehungsweise MyGet.org (Nightly Build) zu beziehen ist. Zudem ist vor der Verwendung der Tag Helpers die Assembly (DLL) einzubinden, in der die Tag-Helper-Klasse kompiliert wurde. Das geschieht mit @addtaghelper "Assembly-Name" entweder zu Beginn einer einzelnen View oder zentral in der Datei /Views/Shared/_ViewStart.cshtml. Die Tag-Helper-Klasse kann in der Haupt-Assembly eines Webprojekts oder einer beliebigen referenzierten Assembly liegen.

Eigene Tags mit Attributen

Sicherlich entsteht der Wunsch, die eigenen HTML-Tags mit Attributen zu parametrisieren. Innerhalb der Process()-Methode der Tag-Helper-Klasse haben Entwickler über die Liste context.AllAttributes Zugriff auf die Attribute, die das eigene Tag in der View besitzt. Schöner ist es aber, der Tag-Helper-Klasse eine öffentliche Property zu geben, die so heißt wie das Tag-Attribut. Dann befüllt ASP.NET MVC die Property mit dem Wert des Tag-Attributs. Alternativ kann man die Namensbindung über die Annotation [HtmlAttributeName("name")] explizit machen.

Die folgende Variante der Klasse DatetimeTagHelper besitzt zwei HTML-Attribute, über die sich Anzeigeformat und Kulturkreiseinstellung im .NET-Stil steuern lassen. Um nur das Datum ohne Uhrzeit in deutschem Format auszugeben, benutzt man in der View: <datetime format="d" culture="de-de" />:

public class DatetimeTagHelper : TagHelper
{
public string Format { get; set; }
public string Culture { get; set; }

public override void Process(TagHelperContext context,
TagHelperOutput output)
{
System.Globalization.CultureInfo ci;
if (!String.IsNullOrEmpty(Culture))
{
ci = new System.Globalization.CultureInfo(Culture);
}
else
{
ci = System.Threading.Thread.CurrentThread.CurrentCulture;
}
output.TagName = "span";
output.Content = DateTime.Now.ToString(Format, ci);
}
}