Taghilfsprogrammkomponenten in ASP.NET Core
Von Scott Addie und Fiyaz Bin Hasan
Eine Taghilfsprogrammkomponente ist ein Taghilfsprogramm, mit dem Sie HTML-Elemente aus serverseitigem Code bedingt ändern oder hinzufügen können. Dieses Feature ist in ASP.NET Core 2.0 oder höher verfügbar.
ASP.NET Core enthält zwei integrierte Taghilfsprogrammkomponenten: head
und body
. Sie befinden sich im Namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers und können in MVC und Razor Pages verwendet werden. Taghilfsprogrammkomponenten erfordern keine Registrierung bei der App in _ViewImports.cshtml
.
Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)
Anwendungsfälle
Zwei gängige Anwendungsfälle für Taghilfsprogrammkomponenten sind:
In den folgenden Abschnitten werden diese Anwendungsfälle beschrieben.
Einfügen in HTML-head-Element
Im HTML-<head>
-Element werden CSS-Dateien häufig mit dem HTML-<link>
-Element importiert. Der folgende Code fügt ein <link>
-Element in das <head>
-Element mit der head
-Taghilfsprogrammkomponente ein:
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressStyleTagHelperComponent : TagHelperComponent
{
private readonly string _style =
@"<link rel=""stylesheet"" href=""/css/address.css"" />";
public override int Order => 1;
public override Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "head",
StringComparison.OrdinalIgnoreCase))
{
output.PostContent.AppendHtml(_style);
}
return Task.CompletedTask;
}
}
}
Für den Code oben gilt:
AddressStyleTagHelperComponent
implementiert TagHelperComponent. Die Abstraktion:- Ermöglicht die Initialisierung der Klasse mit einem TagHelperContext.
- Ermöglicht die Verwendung von Taghilfsprogrammkomponenten zum Hinzufügen oder Ändern von HTML-Elementen.
- Die Order-Eigenschaft definiert die Reihenfolge, in der die Komponenten gerendert werden.
Order
ist erforderlich, wenn mehrere Verwendungsmöglichkeiten für Taghilfsprogrammkomponenten in einer App vorhanden sind. - ProcessAsync vergleicht den TagName-Eigenschaftswert des Ausführungskontexts mit
head
. Wenn der Vergleich zu TRUE ausgewertet wird, wird der Inhalt des_style
-Felds in das HTML<head>
-Element eingefügt.
Einfügen in HTML-body-Element
Die body
-Taghilfsprogrammkomponente kann ein <script>
-Element in das <body>
-Element einfügen. Im folgenden Code wird diese Technik veranschaulicht:
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace RazorPagesSample.TagHelpers
{
public class AddressScriptTagHelperComponent : TagHelperComponent
{
public override int Order => 2;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "body",
StringComparison.OrdinalIgnoreCase))
{
var script = await File.ReadAllTextAsync(
"TagHelpers/Templates/AddressToolTipScript.html");
output.PostContent.AppendHtml(script);
}
}
}
}
Eine separate HTML-Datei wird zum Speichern des <script>
-Elements verwendet. Durch die HTML-Datei wird der Code übersichtlicher und besser verwaltbar. Der vorangehende Code liest den Inhalt von TagHelpers/Templates/AddressToolTipScript.html
und fügt diesen mit der Ausgabe des Taghilfsprogramms an. Diese Datei AddressToolTipScript.html
enthält das folgende Markup:
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
Der vorangehende Code bindet ein Bootstrap-QuickInfo-Widget an ein beliebiges <address>
-Element, das ein printable
-Attribut enthält. Der Effekt wird sichtbar, wenn ein Mauszeiger über das Element bewegt wird.
Registrieren einer Komponente
Eine Taghilfsprogrammkomponente muss der Sammlung „Taghilfsprogrammkomponenten“ der App hinzugefügt werden. Es gibt drei Möglichkeiten, der Sammlung Taghilfsprogrammkomponenten hinzuzufügen:
- Registrierung über Dienstcontainer
- Registrierung über Razor-Datei
- Registrierung über Seitenmodell oder Controller
Registrierung über Dienstcontainer
Wenn die Klasse der Taghilfsprogrammkomponente nicht mit ITagHelperComponentManager verwaltet wird, muss sie mit dem Abhängigkeitsinjektionssystem (Dependency Injection, DI) registriert werden. Der folgende Startup.ConfigureServices
-Code registriert die AddressStyleTagHelperComponent
- und AddressScriptTagHelperComponent
- -Klassen mit einer vorübergehenden Lebensdauer:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddTransient<ITagHelperComponent,
AddressScriptTagHelperComponent>();
services.AddTransient<ITagHelperComponent,
AddressStyleTagHelperComponent>();
}
Registrierung über Razor-Datei
Wenn die Taghilfsprogrammkomponente nicht mit Abhängigkeitsinjektion registriert wird, kann sie über eine Razor Pages-Seite oder eine MVC-Ansicht registriert werden. Diese Technik wird verwendet, um das injizierte Markup und die Reihenfolge der Komponentenausführung aus einer Razor-Datei zu steuern.
ITagHelperComponentManager
dient zum Hinzufügen von Taghilfsprogrammkomponenten oder zum Entfernen aus der App. Im folgenden Code wird diese Technik mit AddressTagHelperComponent
veranschaulicht:
@using RazorPagesSample.TagHelpers;
@using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
@inject ITagHelperComponentManager manager;
@{
string markup;
if (Model.IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
manager.Components.Add(new AddressTagHelperComponent(markup, 1));
}
Für den Code oben gilt:
- Die
@inject
-Direktive stellt eine Instanz vonITagHelperComponentManager
zur Verfügung. Die Instanz wird einer Variablen mit dem Namenmanager
für den Downstreamzugriff in der Razor-Datei zugewiesen. - Eine Instanz von
AddressTagHelperComponent
wird der Sammlung „Taghilfsprogrammkomponenten“ der App hinzugefügt.
AddressTagHelperComponent
wird geändert, um einen Konstruktor zu berücksichtigen, der die markup
- und order
-Parameter annimmt:
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
Der bereitgestellte markup
-Parameter wird in ProcessAsync
wie folgt verwendet:
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
TagHelperContent childContent = await output.GetChildContentAsync();
string content = childContent.GetContent();
output.Content.SetHtmlContent(
$"<div>{content}<br>{_markup}</div>{_printableButton}");
}
}
Registrierung über Seitenmodell oder Controller
Wenn die Taghilfsprogrammkomponente nicht mit Abhängigkeitsinjektion registriert wird, kann sie über ein Razor Pages-Seitenmodell oder einen MVC-Controller registriert werden. Diese Methode eignet sich zum Trennen von C#-Logik von Razor-Dateien.
Die Konstruktorinjektion wird verwendet, um auf eine Instanz von ITagHelperComponentManager
zuzugreifen. Die Taghilfsprogrammkomponente wird der Sammlung „Taghilfsprogrammkomponenten“ der Instanz hinzugefügt. Das folgende Razor Pages-Seitenmodell veranschaulicht diese Technik mit AddressTagHelperComponent
:
using System;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPagesSample.TagHelpers;
public class IndexModel : PageModel
{
private readonly ITagHelperComponentManager _tagHelperComponentManager;
public bool IsWeekend
{
get
{
var dayOfWeek = DateTime.Now.DayOfWeek;
return dayOfWeek == DayOfWeek.Saturday ||
dayOfWeek == DayOfWeek.Sunday;
}
}
public IndexModel(ITagHelperComponentManager tagHelperComponentManager)
{
_tagHelperComponentManager = tagHelperComponentManager;
}
public void OnGet()
{
string markup;
if (IsWeekend)
{
markup = "<em class='text-warning'>Office closed today!</em>";
}
else
{
markup = "<em class='text-info'>Office open today!</em>";
}
_tagHelperComponentManager.Components.Add(
new AddressTagHelperComponent(markup, 1));
}
}
Für den Code oben gilt:
- Die Konstruktorinjektion wird verwendet, um auf eine Instanz von
ITagHelperComponentManager
zuzugreifen. - Eine Instanz von
AddressTagHelperComponent
wird der Sammlung „Taghilfsprogrammkomponenten“ der App hinzugefügt.
Erstellen einer Komponente
So erstellen Sie eine benutzerdefinierte Taghilfsprogrammkomponente:
- Erstellen Sie eine öffentliche Klasse, die von TagHelperComponentTagHelper ableitet ist.
- Wenden Sie ein
[HtmlTargetElement]
-Attribut auf die Klasse an. Geben Sie den Namen des HTML-Zielelements an. - Optional: Wenden Sie ein
[EditorBrowsable(EditorBrowsableState.Never)]
-Attribut auf die Klasse an, um die Anzeige des Typs in IntelliSense zu unterdrücken.
Der folgende Code erstellt eine benutzerdefinierte Taghilfsprogrammkomponente, das als Ziel das <address>
-HTML-Element aufweist:
using System.ComponentModel;
using Microsoft.AspNetCore.Mvc.Razor.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Logging;
namespace RazorPagesSample.TagHelpers
{
[HtmlTargetElement("address")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class AddressTagHelperComponentTagHelper : TagHelperComponentTagHelper
{
public AddressTagHelperComponentTagHelper(
ITagHelperComponentManager componentManager,
ILoggerFactory loggerFactory) : base(componentManager, loggerFactory)
{
}
}
}
Verwenden Sie die benutzerdefinierte address
-Taghilfsprogrammkomponente zum Einfügen von HTML-Markup wie hier gezeigt:
public class AddressTagHelperComponent : TagHelperComponent
{
private readonly string _printableButton =
"<button type='button' class='btn btn-info' onclick=\"window.open(" +
"'https://binged.it/2AXRRYw')\">" +
"<span class='glyphicon glyphicon-road' aria-hidden='true'></span>" +
"</button>";
public override int Order => 3;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
if (string.Equals(context.TagName, "address",
StringComparison.OrdinalIgnoreCase) &&
output.Attributes.ContainsName("printable"))
{
var content = await output.GetChildContentAsync();
output.Content.SetHtmlContent(
$"<div>{content.GetContent()}</div>{_printableButton}");
}
}
}
Die obige ProcessAsync
-Methode injiziert den für SetHtmlContent bereitgestellten HTML-Code in das entsprechende <address>
-Element. Die Einfügung tritt auf, wenn:
- Der
TagName
-Eigenschaftswert des Ausführungskontextsaddress
entspricht. - Das entsprechende
<address>
-Element über einprintable
-Attribut verfügt.
Beispielsweise wird die if
-Anweisung bei der Verarbeitung des folgenden <address>
-Elements zu TRUE ausgewertet:
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
Zusätzliche Ressourcen
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für