Tag Helpers dans ASP.NET Core

Par Rick Anderson

Que sont les Tag Helpers ?

Les Tag Helpers permettent au code côté serveur de participer à la création et au rendu des éléments HTML dans les fichiers Razor. Par exemple, le ImageTagHelper intégré peut ajouter un numéro de version au nom de l’image. Chaque fois que l’image change, le serveur en génère une nouvelle version unique, pour que les clients soient sûrs d’obtenir l’image actuelle (au lieu d’une image mise en cache obsolète). Il existe de nombreux Tag Helpers pour les tâches courantes (par exemple la création de formulaires ou de liens, le chargement de ressources, etc.) et bien d’autres encore, dans les dépôts GitHub publics et sous forme de packages NuGet. Les Tag helpers sont créés en c#, et ils ciblent des éléments HTML en fonction de la balise parente, du nom d’attribut ou du nom de l’élément. Par exemple, le LabelTagHelper intégré peut cibler l’élément <label> HTML quand les attributs LabelTagHelper sont appliqués. Si vous connaissez déjà les HTML Helpers, découvrez les Tag Helpers, qui permettent de réduire les transitions explicites entre HTML et C# dans les vues Razor. Dans de nombreux cas, les HTML Helpers offrent une autre approche par rapport à un Tag Helper spécifique. Toutefois, il est clair que les Tag Helpers ne remplacent pas les HTML Helpers, et qu’il n’existe pas toujours un Tag Helper pour chaque HTML Helper. Comparaison des Tag Helpers aux HTML Helpers explique les différences de façon plus approfondie.

Les Tag Helpers ne sont pas pris en charge dans les composants Razor. Pour plus d’informations, consultez Composants ASP.NET Core Razor.

Ce que fournissent des Tag helpers

Expérience de développement compatible HTML

Généralement, le balisage Razor utilisant les Tag Helpers ressemble à di HTML standard. Les concepteurs frontaux familiarisés avec HTML, CSS et JavaScript peuvent modifier Razor sans apprendre la syntaxe Razor C#.

Un environnement IntelliSense riche pour la création de code HTML et de balisage Razor

Cet environnement se démarque fortement des HTML Helpers, correspondant à la précédente approche de la création côté serveur de balisage dans les affichages Razor. Comparaison des Tag Helpers aux HTML Helpers explique les différences de façon plus approfondie. Prise en charge IntelliSense des Tag Helpers explique l’environnement IntelliSense. Même les développeurs habitués à la syntaxe Razor C# sont plus productifs en utilisant des Tag Helpers qu’en écrivant des balisages Razor C#.

Un moyen d’améliorer votre productivité et votre capacité à produire du code plus robuste, fiable et facile à gérer en utilisant des informations uniquement disponibles sur le serveur

Par exemple, l’ancien usage pour la mise à jour des images consistait à modifier le nom de l’image quand vous modifiiez l’image. Les images doivent être efficacement mises en cache pour des raisons de performance, et à moins de modifier le nom d’une image, les clients risquent d’obtenir une copie obsolète. Auparavant, une fois qu’une image avait été modifiée, le nom devait être modifié et chaque référence à l’image dans l’application web avait besoin d’être mise à jour. Non seulement ce travail était fastidieux, mais il engendrait facilement des erreurs (vous pouviez oublier une référence, entrer la mauvaise chaîne par inadvertance, etc.). Le ImageTagHelper intégré peut s’en charger automatiquement à votre place. Le ImageTagHelper peut ajouter un numéro de version au nom de l’image, si bien que dès que l’image change, le serveur génère automatiquement une nouvelle version unique de l’image. Les clients sont sûrs d’obtenir l’image actuelle. Cette robustesse et cette économie de travail sont inhérentes à l’utilisation du ImageTagHelper.

La plupart des Tag Helpers intégrés ciblent les éléments HTML standard et fournissent des attributs côté serveur pour l’élément. Par exemple, l’élément <input> utilisé dans de nombreuses vues dans le dossier Views/Account contient l’attribut asp-for. Cet attribut extrait le nom de la propriété de modèle spécifiée dans le code HTML restitué. Examinons une vue Razor avec le modèle suivant :

public class Movie
{
    public int ID { get; set; }
    public string Title { get; set; }
    public DateTime ReleaseDate { get; set; }
    public string Genre { get; set; }
    public decimal Price { get; set; }
}

Le balisage Razor suivant :

<label asp-for="Movie.Title"></label>

Génère le code HTML suivant :

<label for="Movie_Title">Title</label>

L’attribut asp-for est rendu disponible par la propriété For dans le LabelTagHelper. Pour plus d’informations, consultez Créer des Tag Helpers.

Gestion de l’étendue des Tag Helpers

L’étendue des Tag Helpers est contrôlée par une combinaison de @addTagHelper, @removeTagHelper et du caractère d’annulation « ! ».

@addTagHelper rend les Tag Helpers disponibles

Si vous créez une application web ASP.NET Core nommée AuthoringTagHelpers, le fichier suivant Views/_ViewImports.cshtml est ajouté à votre projet :

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

La directive @addTagHelper rend les Tag Helpers disponibles dans l’affichage. Dans cet exemple, le fichier d’affichage est Pages/_ViewImports.cshtml, qui est hérité par défaut par tous les fichiers dans le dossier et les sous-dossiers Pages. Les Tag Helpers sont ainsi disponibles. Le code ci-dessus utilise la syntaxe d’expressions génériques (« * ») pour spécifier que tous les Tag Helpers dans l’assembly spécifié (Microsoft.AspNetCore.Mvc.TagHelpers) sont disponibles pour chaque fichier d’affichage du répertoire ou sous-répertoire Views. Le premier paramètre après @addTagHelper spécifie les Tag Helpers à charger (nous utilisons « * » pour tous les Tag Helpers), et le deuxième paramètre « Microsoft.AspNetCore.Mvc.TagHelpers » spécifie l’assembly qui contient les Tag Helpers. Microsoft.AspNetCore.Mvc.TagHelpers est l’assembly des Tag Helpers ASP.NET Core intégrés.

Pour exposer tous les Tag Helpers inclus dans ce projet (ce qui crée un assembly nommé AuthoringTagHelpers), utilisez ce qui suit :

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, AuthoringTagHelpers

Si votre projet contient un EmailTagHelper avec l’espace de noms par défaut (AuthoringTagHelpers.TagHelpers.EmailTagHelper), vous pouvez fournir le nom qualifié complet (FQN) des Tag helpers :

@using AuthoringTagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.EmailTagHelper, AuthoringTagHelpers

Pour ajouter un Tag Helper à un affichage à l’aide d’un FQN, vous ajoutez d’abord ce FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper), puis le nom de l’assembly (AuthoringTagHelpers). La plupart des développeurs préfèrent utiliser la syntaxe d’expressions génériques « * ». Celle-ci permet d’insérer le caractère générique « * » en guise de suffixe dans un FQN. Par exemple, chacune des directives suivantes affiche le EmailTagHelper :

@addTagHelper AuthoringTagHelpers.TagHelpers.E*, AuthoringTagHelpers
@addTagHelper AuthoringTagHelpers.TagHelpers.Email*, AuthoringTagHelpers

Comme mentionné précédemment, l’ajout de la directive @addTagHelper au fichier Views/_ViewImports.cshtml met le Tag Helper à la disposition de tous les fichiers d’affichage inclus dans le répertoire et les sous-répertoires Views. Vous pouvez utiliser la directive @addTagHelper dans des fichiers d’affichage spécifiques si vous choisissez d’exposer le Tag Helper uniquement à ces affichages.

@removeTagHelper supprime les Tag Helpers

Le@removeTagHelper a les deux mêmes paramètres que @addTagHelper, et il supprime un Tag helper ajoutée précédemment. Par exemple, @removeTagHelper appliqué à une vue supprime le Tag helper spécifié de la vue. Utiliser @removeTagHelper dans un fichier Views/Folder/_ViewImports.cshtml supprime le Tag Helper à partir de toutes les vues du dossier.

Contrôle de l’étendue des Tag Helpers à l’aide du fichier _ViewImports.cshtml

Vous pouvez ajouter un fichier _ViewImports.cshtml à tout dossier d’affichage. Le moteur d’affichage applique les directives de ce fichier et du fichier Views/_ViewImports.cshtml. Si vous avez ajouté un fichier Views/Home/_ViewImports.cshtml vide pour les affichages Home, rien n’est modifié car le fichier _ViewImports.cshtml est additif. Toute directive @addTagHelper que vous ajoutez au fichier Views/Home/_ViewImports.cshtml (qui n’est pas dans le fichier Views/_ViewImports.cshtml par défaut) expose ces Tag Helpers uniquement aux affichages inclus dans le dossier Home.

Refus d’éléments individuels

Vous pouvez désactiver un Tag Helper au niveau de l’élément à l’aide du caractère d’annulation de Tag Helper (« ! »). Par exemple, la validation Email est désactivée dans <span> à l’aide du caractère d’annulation de Tag Helper :

<!span asp-validation-for="Email" class="text-danger"></!span>

Vous devez appliquer le caractère d’annulation de Tag Helper à la balise d’ouverture et de fermeture. (L’éditeur Visual Studio ajoute automatiquement le caractère d’annulation à la balise de fermeture quand vous en ajoutez un à la balise d’ouverture). Après avoir ajouté le caractère d’annulation, l’élément et les attributs du Tag Helper ne s’affichent plus dans une police caractéristique.

Utilisation de @tagHelperPrefix pour rendre l’utilisation du Tag Helper explicite

La directive @tagHelperPrefix vous permet de spécifier une chaîne de préfixe de balise pour activer la prise en charge des Tag Helpers et rendre leur utilisation explicite. Par exemple, vous pouvez ajouter le balisage suivant au fichier Views/_ViewImports.cshtml :

@tagHelperPrefix th:

Dans l’image de code ci-dessous, le préfixe du Tag Helper a la valeur th:, si bien que seuls les éléments qui utilisent le préfixe th: prennent en charge les Tag Helpers (les éléments activés pour les Tag Helpers ont une police caractéristique). Les éléments <label> et <input> ont le préfixe du Tag Helper et sont activés, à la différence de l’élément <span>.

Razor markup with Tag Helper prefix set to

Les mêmes règles de hiérarchie qui s’appliquent à @addTagHelper s’appliquent aussi à @tagHelperPrefix.

Tag Helpers à fermeture automatique

De nombreux Tag Helpers ne peuvent pas être utilisés en tant que balises à fermeture automatique. Certains Tag Helpers sont conçus en tant que balises à fermeture automatique. L’utilisation d’un Tag Helper qui n’a pas été conçu pour être à fermeture automatique supprime la sortie rendue. La fermeture automatique d’un Tag Helper aboutit à une balise à fermeture automatique dans la sortie rendue. Pour plus d’informations, consultez cette remarque dans Création de Tag Helpers.

C# dans un attribut ou une déclaration Tag Helpers

Les Tag Helpers n’autorisent pas C# dans l’attribut ou la zone de déclaration de balise de l’élément. Par exemple, le code suivant n’est pas valide :

<input asp-for="LastName"  
       @(Model?.LicenseId == null ? "disabled" : string.Empty) />

Le code précédent peut être écrit ainsi :

<input asp-for="LastName" 
       disabled="@(Model?.LicenseId == null)" />

Normalement, l’opérateur @ insère une représentation textuelle d’une expression dans le balisage HTML rendu. Toutefois, lorsqu’une expression prend la valeur logique false, l’infrastructure supprime l’attribut à la place. Dans l’exemple précédent, l’attribut disabled est défini sur true si Model ou LicenseId est null.

Initialiseurs de Tag Helpers

Bien que les attributs puissent être utilisés pour configurer des instances individuelles de Tag Helpers, ITagHelperInitializer<TTagHelper> peut être utilisé pour configurer toutes les instances de Tag Helpers d’un type spécifique. Considérez l’exemple suivant d’initialiseur de Tag Helpers qui configure l’attribut asp-append-version ou la propriété AppendVersion pour toutes les instances de dans l’application ScriptTagHelper :

public class AppendVersionTagHelperInitializer : ITagHelperInitializer<ScriptTagHelper>
{
    public void Initialize(ScriptTagHelper helper, ViewContext context)
    {
        helper.AppendVersion = true;
    }
}

Pour utiliser l’initialiseur, configurez-le en l’inscrivant dans le cadre du démarrage de l’application :

builder.Services.AddSingleton
    <ITagHelperInitializer<ScriptTagHelper>, AppendVersionTagHelperInitializer>();

Génération automatique de version de Tag Helper en dehors de wwwroot

Pour qu’un Tag Helper génère une version pour un fichier statique en dehors de wwwroot, consultez Servir des fichiers à partir de plusieurs emplacements

Prise en charge IntelliSense des Tag Helpers

Envisagez d’écrire un élément <label> HTML. Dès que vous entrez <l dans l’éditeur Visual Studio, IntelliSense affiche les éléments correspondants :

After typing

Non seulement vous obtenez de l’aide HTML, mais aussi l’icône (le symbole « @ » avec <> en dessous).

The

L’icône identifie l’élément comme étant ciblé par les Tag Helpers. Les éléments HTML purs (comme fieldset) présentent l’icône « <> ».

Une balise <label> HTML pure affiche la balise HTML (avec le thème de couleur Visual Studio par défaut) dans une police marron, les attributs en rouge et les valeurs d’attribut en bleu.

Example

Après avoir entré <label, IntelliSense répertorie les attributs HTML/CSS disponibles et les attributs ciblés par les Tag Helpers :

The user has typed an opening bracket and the HTML element name

La saisie semi-automatique des instructions par IntelliSense vous permet d’appuyer sur la touche Tab pour compléter automatiquement l’instruction avec la valeur sélectionnée :

The user has typed an opening bracket, the HTML element name

Dès qu’un attribut de Tag Helper est entré, les polices de la balise et de l’attribut changent. En utilisant le thème de couleur « Bleu » ou « Clair » par défaut de Visual Studio, la police est en violet gras. Si vous utilisez le thème « Foncé », la police est en bleu-vert gras. Les images de ce document ont été prises à l’aide du thème par défaut.

The user selected

Vous pouvez entrer le raccourci CompleteWord Visual Studio (Ctrl+Espace par défaut) à l’intérieur des guillemets doubles ("") pour aller dans C#, de la même façon que dans une classe C#. IntelliSense affiche toutes les méthodes et propriétés dans le modèle de page. Les méthodes et propriétés sont disponibles car le type de propriété est ModelExpression. Dans l’image ci-dessous, je modifie l’affichage Register, donc RegisterViewModel est disponible.

The user types

IntelliSense répertorie les propriétés et méthodes disponibles pour le modèle dans la page. Le riche environnement IntelliSense vous aide à sélectionner la classe CSS :

The user types

The user types

Comparaison des Tag Helpers aux HTML Helpers

Les Tag Helpers s’attachent aux éléments HTML dans les vues Razor, tandis que les HTML Helpers sont appelés en tant que méthodes intercalées avec du HTML dans les vues Razor. Examinez le balisage Razor suivant, qui crée une étiquette HTML avec la classe CSS « caption » :

@Html.Label("FirstName", "First Name:", new {@class="caption"})

L’arobase (@) signale le début du code à Razor. Les deux paramètres suivants (« FirstName » et « First Name: ») sont des chaînes, par conséquent, IntelliSense ne sert à rien. Le dernier argument :

new {@class="caption"}

Est un objet anonyme utilisé pour représenter des attributs. Étant donné que class est un mot clé réservé en C#, vous utilisez le symbole @ pour forcer le code C# à interpréter @class= comme un symbole (nom de propriété). Pour un concepteur frontal (une personne qui connaît bien le code HTML, CSS et JavaScript et d’autres technologies clientes, mais qui ne connaît pas C# et Razor), la majorité de la ligne LUI est étrangère. La ligne entière doit être créée sans l’aide d’IntelliSense.

Avec LabelTagHelper, le même balisage peut s’écrire ainsi :

<label class="caption" asp-for="FirstName"></label>

Avec la version Tag Helper, dès que vous entrez <l dans l’éditeur Visual Studio, IntelliSense affiche les éléments correspondants :

The user types

IntelliSense vous aide à écrire la ligne entière.

L’image de code suivante montre la partie formulaire de l’affichage Views/Account/Register.cshtmlRazor généré à partir du modèle ASP.NET 4.5.x MVC inclus dans Visual Studio.

Razor markup for the form portion of the Register Razor view for ASP.NET 4.5 MVC project template

L’éditeur Visual Studio présente le code C# avec un arrière-plan gris. Par exemple, le HTML Helper AntiForgeryToken :

@Html.AntiForgeryToken()

est présenté avec un arrière-plan gris. La plupart du balisage dans l’affichage Register est en C#. Comparez-le à l’approche équivalente qui utilise des Tag Helpers :

Razor markup with Tag Helpers for the form portion of the Register Razor view for an ASP.NET Core project template

Le balisage est beaucoup plus claire et facile à lire, modifier et gérer qu’avec l’approche des HTML Helpers. Le code C# est réduit au minimum que le serveur doit savoir. L’éditeur Visual Studio présente le balisage ciblé par un Tag Helper dans une police caractéristique.

Examinez le groupe Email :

<div class="form-group">
    <label asp-for="Email" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
</div>

Chacun des attributs « asp- » a la valeur « Email », mais « Email » n’est pas une chaîne. Dans ce contexte, « Email » est la propriété de l’expression du modèle C# pour RegisterViewModel.

L’éditeur Visual Studio vous aide à écrire tout le balisage dans l’approche Tag Helpers du formulaire d’inscription, tandis que Visual Studio ne fournit aucune aide pour la plupart du code dans l’approche HTML Helpers. Prise en charge IntelliSense des Tag Helpers décrit précisément l’utilisation de Tag Helpers dans l’éditeur Visual Studio.

Comparaison des Tag Helpers aux contrôles de serveur web

  • Les Tag Helpers ne sont pas propriétaires de l’élément auquel ils sont associés ; ils participent simplement au rendu de l’élément et du contenu. Les contrôles de serveur web ASP.NET sont déclarés et appelés dans une page.

  • Les contrôles de serveur web ASP.NET ont un cycle de vie non trivial qui peut rendre le développement et le débogage difficiles.

  • Les contrôles de serveur web vous permettent d’ajouter des fonctionnalités aux éléments DOM du client à l’aide d’un contrôle client. Les Tag Helpers n’ont pas de DOM.

  • Les contrôles de serveur web incluent une détection automatique du navigateur. Les Tag Helpers n’ont pas connaissance du navigateur.

  • Plusieurs Tag Helpers peuvent agir sur le même élément (consultez Éviter les conflits de Tag Helpers) alors que généralement vous ne pouvez pas composer des contrôles de serveur web.

  • Les Tag Helpers peuvent modifier la balise et le contenu des éléments HTML auxquels ils s’étendent, mais pas modifier directement quoi que ce soit d’autre dans une page. Les contrôles de serveur web ont une étendue moins spécifique et peuvent effectuer des actions qui affectent d’autres parties de votre page, ce qui peut entraîner des effets secondaires involontaires.

  • Les contrôles de serveur web utilisent des convertisseurs de type pour convertir les chaînes en objets. Avec les Tag Helpers, vous travaillez en mode natif en C#, donc vous n’avez pas besoin d’effectuer de conversions de type.

  • Les contrôles de serveur web utilisent System.ComponentModel pour implémenter le comportement au moment de l’exécution et de la conception des composants et des contrôles. System.ComponentModel inclut les classes et les interfaces de base servant à l’implémentation des attributs et des convertisseurs de type, à la liaison à des sources de données et à la gestion des licences des composants. Comparez-les aux Tag Helpers, qui sont généralement dérivés de TagHelper et à la classe de base TagHelper qui expose uniquement deux méthodes, Process et ProcessAsync.

Personnalisation de la police des éléments Tag Helper

Vous pouvez personnaliser la police et les couleurs depuis Outils>Options>Environnement>Polices et couleurs :

Options dialog in Visual Studio

Tag Helpers intégrés d’ASP.NET Core

Ancre

Cache

Composant

Cache distribué

Environnement

Forme

Action de formulaire

Image

Entrée

Étiquette

Lien

Partiel

Conserver l’état des composants

Script

Sélectionner

Textarea

Message de validation

Résumé de validation

Ressources supplémentaires