Introduction aux aides à l'étiquette personnalisée dans ASP.NET MVC

Les applications Web modernes exigent un code de vue propre, durable et réutilisable. ASP.NET Core MVC fournit des aides-étiquettes comme un puissant mécanisme côté serveur pour transformer et générer le balisage HTML directement dans les vues de Razor. Bien que le framework soit livré avec un riche ensemble d'aide-étiquettes intégrées pour les formulaires, la validation, le cache et le rendu spécifique à l'environnement, les projets du monde réel nécessitent souvent des composants adaptés qui encapsulent les modèles de logique et de présentation spécifiques au domaine.

En déplaçant la génération de HTML complexe et la logique conditionnelle dans des classes d'aide aux tags réutilisables, vous séparez les préoccupations de présentation du balisage de vue, améliorez la testabilité et réduisez la duplication sur les grandes bases de code. Cet article fournit un guide complet pour construire des aides aux tags personnalisées dans ASP.NET Core MVC, couvrant tout, de la structure de classe de base et la liaison des attributs aux scénarios avancés tels que l'injection de dépendance, le traitement asynchrone et les composants d'aide aux tags.

Comprendre les assistants de Tag dans ASP.NET Core

Les helpers de tag sont des composants côté serveur qui participent au rendu des éléments HTML dans les vues Razor. Ils vous permettent d'attacher le code C# à des éléments HTML spécifiques ou des noms d'éléments personnalisés, transformant le balisage avant qu'il ne soit envoyé au client. Contrairement aux helpers HTML (qui utilisent la méthode appelle comme ), les helpers de tag fonctionnent en fonction de la syntaxe HTML existante, rendant les vues plus naturelles pour les concepteurs et les développeurs front-end.

Par exemple, l'aide-étiquette intégrée fusionne les attributs de contrôleur et d'action dans l'URL correcte. Les aides-étiquettes peuvent modifier les attributs, remplacer l'élément entier, ajouter ou supprimer des classes CSS et même injecter des HTML supplémentaires. Elles fonctionnent pendant le pipeline d'exécution de la vue Razor et ont un accès complet au contexte de requête actuel, aux données du modèle et aux services enregistrés.

Modèle d'exécution à l'aide du serveur

Lorsqu'une vue Razor est compilée, les helpers de tag sont découverts par des assemblages et des directives . Le framework évalue chaque élément HTML contre tous les helpers de tag enregistrés, invoquant leurs méthodes ou lorsqu'une correspondance est trouvée. Cela se produit avant que la sortie HTML finale ne soit générée, permettant aux helpers de tag d'enrichir ou de remplacer les éléments dynamiquement.

Principales différences par rapport aux autres outils de composition

  • Helpers HTML: Nécessite des appels de méthode C# à l'intérieur des blocs de rasoir (), qui peuvent briser le flux HTML-centric.
  • Parties:[ Bon pour réutiliser des morceaux statiques de balisage mais ne pas avoir la capacité de changer de structure programmatiquement en fonction de la logique côté serveur sans modèles de vue supplémentaires.
  • Voir les composants: Idéal pour les widgets complexes et axés sur les données avec leur propre logique et rendu, mais ils nécessitent une syntaxe de classe et d'invocation séparée (.

Pourquoi créer des aides à l'étiquette personnalisées?

Bien que les assistants de tag intégrés couvrent de nombreux scénarios communs, les assistants de tag personnalisés offrent des avantages uniques qui améliorent directement la qualité du code et la productivité du développeur.

  • Encapsuler les motifs de marquage complexes – Répéter la plaque de chaudière HTML (comme les composants de cartes structurées, les tables de données ou les boutons style) peut être encapsulé en un seul élément personnalisé.
  • Enforcer la cohérence de conception[ – Une helper de tags personnalisée ou peut imposer des classes CSS cohérentes, des attributs d'accessibilité et des modèles de liaison de données, réduisant ainsi les risques d'incohérences de l'assurance-chômage.
  • Improuvez la lisibilité de la vue – Au lieu de blocs imbriqués et de blocs C# conditionnels, une seule étiquette avec quelques attributs est beaucoup plus facile à scanner et à entretenir.
  • Activer le test unitaire de la vue Logic – Parce que les assistants de tags sont des classes simples qui produisent du HTML, vous pouvez écrire des tests unitaires pour vérifier la sortie générée pour diverses entrées, quelque chose de difficile à réaliser avec le code Razor en ligne.
  • – Une bibliothèque d'aide-étiquettes personnalisées peut être emballée comme un composant NuGet et partagée entre plusieurs solutions, en favorisant une boîte à outils d'interface utilisateur cohérente.

Création d'un assistant de balise personnalisé de base

Chaque helper de tag personnalisé hérite de la classe (ou implémente directement) et est décoré de l'attribut pour spécifier quel élément HTML ou attribut il cible. Le noyau de la logique vit à l'intérieur de la méthode (ou de son homologue asynchrone ).

Étape 1: Définir la classe d'aide à l'étiquette

Créez une nouvelle classe C# dans votre projet, généralement dans un dossier . Héritage de et appliquez l'attribut avec le nom de l'élément que vous comptez utiliser dans vos vues.

[HtmlTargetElement("custom-card")]
public class CustomCardTagHelper : TagHelper
{
 public string Title { get; set; }
 public string CssClass { get; set; } = "card-default";

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 // Replace the custom tag with a div and add the desired structure
 output.TagName = "div";
 output.Attributes.SetAttribute("class", $"card {CssClass}");

 // Build inner content
 output.Content.SetHtmlContent(
 $@"<div class=""card-header"">{Title}</div>
 <div class=""card-body"">
 {output.Content.GetContent()}
 </div>"
 );
 }
}

Étape 2: Comprendre le contenu de TagHelper et le rendement de TagHelper

Le fournit des informations sur l'élément courant et ses attributs. Le vous permet de modifier le nom, les attributs et le contenu de la balise de l'élément. Vous pouvez également utiliser pour le texte simple ou pour le HTML brut. Pour préserver le contenu original (p. ex., les éléments enfants dans la balise personnalisée), vous appelez comme indiqué ci-dessus.

Étape 3: Enregistrer l'aide à l'étiquette

Les assistants d'étiquette sont automatiquement découverts s'ils sont dans le même assemblage que l'application. Si vos assistants d'étiquette résident dans une bibliothèque de classe séparée, vous devez ajouter une directive dans :

@addTagHelper *, MyApp.TagHelpers

Le format est ou une carte joker avec pour inclure tous les assistants de tags de cette assemblée. Vous pouvez également utiliser pour exclure des assistants spécifiques.

Étape 4: Utilisez l'aide à l'étiquette dans une vue rasoir

Avec l'enregistrement en place, vous pouvez utiliser l'élément personnalisé:

<custom-card title="Welcome" css-class="card-primary">
 This is the body content
</custom-card>

Cela produit:

<div class="card card-primary">
 <div class="card-header">Welcome</div>
 <div class="card-body">
 This is the body content
 </div>
</div>

Techniques avancées d'aide à l'étiquette

Utilisation des attributs et de la liaison des biens

Les helpers de tag personnalisés peuvent accepter plusieurs attributs, y compris des types complexes et des expressions de modèle. Par exemple, un helper de tag qui rend une entrée de formulaire peut lier une propriété à une expression de modèle :

[HtmlTargetElement("email-input")]
public class EmailInputTagHelper : TagHelper
{
 [HtmlAttributeName("asp-for")]
 public ModelExpression For { get; set; }

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 output.TagName = "input";
 output.Attributes.SetAttribute("type", "email");
 output.Attributes.SetAttribute("id", For.Name);
 output.Attributes.SetAttribute("name", For.Name);
 output.Attributes.SetAttribute("value", For.Model?.ToString() ?? "");
 }
}

L'attribut map la propriété C# à un nom d'attribut HTML spécifique. L'utilisation de vous donne accès aux métadonnées du modèle pour une intégration complète avec la logique de validation et d'affichage.

Traitement asynchrone

Si votre helper de tags doit effectuer des opérations d'E/S (p. ex., récupérer des données dans une base de données), remplacez par:

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
 var data = await _someService.GetDataAsync();
 output.Content.SetHtmlContent(data);
}

Injection de dépendance dans les assistants d'étiquette

Tag helpers support l'injection de constructeur comme tout autre service MVC. Il suffit d'ajouter votre dépendance au constructeur, et le conteneur DI va le résoudre:

public class UserProfileTagHelper : TagHelper
{
 private readonly IUserService _userService;

 public UserProfileTagHelper(IUserService userService)
 {
 _userService = userService;
 }

 public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
 {
 var user = await _userService.GetCurrentUserAsync();
 // render user profile markup
 }
}

Notez que les helpers de tag sont transitoires par défaut ; une nouvelle instance est créée pour chaque utilisation dans une vue.

Composants d'aide à l'étiquette pour l'injection HTML globale

Introduit dans ASP.NET Core 2.1, Tag Helper Components vous permet d'injecter le balisage dans chaque réponse à l'échelle mondiale, généralement utilisée pour regrouper des scripts, des styles ou des analyses.

public class GlobalScriptTagHelperComponent : TagHelperComponent
{
 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 if (output.TagName == "body" && output.Attributes.ContainsName("data-scripts"))
 {
 output.PostContent.AppendHtml("<script src='/js/global.js'></script>");
 }
 }
}

// In Startup.ConfigureServices
services.AddTransient<ITagHelperComponent, GlobalScriptTagHelperComponent>();

Exemples pratiques pour la composition de la vue

1. Aide à l'étiquette d'emballage conditionnel

Envelopper le contenu avec un élément supplémentaire seulement si une condition est remplie, utile pour les conteneurs de mise en page réactifs:

[HtmlTargetElement("if-wrapper")]
public class IfWrapperTagHelper : TagHelper
{
 public bool Condition { get; set; }

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 if (!Condition)
 {
 // Remove the wrapping element, output only the child content
 output.TagName = null;
 output.Content.SetContent(output.Content.GetContent());
 }
 else
 {
 output.TagName = "div";
 output.Attributes.SetAttribute("class", "wrapper");
 }
 }
}

2. Image avec chargement paresseux et srcset

Créer un helper de tag qui génère des tags responsive avec attribut et plusieurs sources :

[HtmlTargetElement("lazy-image")]
public class LazyImageTagHelper : TagHelper
{
 public string Src { get; set; }
 public string Srcset { get; set; }
 public string Alt { get; set; }
 public string CssClass { get; set; }

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 output.TagName = "img";
 output.Attributes.SetAttribute("src", Src);
 if (!string.IsNullOrEmpty(Srcset))
 output.Attributes.SetAttribute("srcset", Srcset);
 output.Attributes.SetAttribute("alt", Alt);
 output.Attributes.SetAttribute("loading", "lazy");
 if (!string.IsNullOrEmpty(CssClass))
 output.Attributes.SetAttribute("class", CssClass);
 }
}

3. Sommaire de validation avec structure personnalisée

Au lieu d'utiliser l'aide de la balise de synthèse de validation intégrée, créez une image qui ajoute des icônes et un style personnalisés :

[HtmlTargetElement("custom-validation-summary")]
public class CustomValidationSummaryTagHelper : TagHelper
{
 [HtmlAttributeName("asp-validation-summary")]
 public ValidationSummary ValidationSummary { get; set; }

 [ViewContext]
 public ViewContext ViewContext { get; set; }

 public override void Process(TagHelperContext context, TagHelperOutput output)
 {
 var viewData = ViewContext.ViewData;
 var errors = viewData.ModelState.Where(s => s.Value.Errors.Count > 0).SelectMany(s => s.Value.Errors).ToList();

 if (errors.Count == 0)
 {
 output.SuppressOutput();
 return;
 }

 output.TagName = "div";
 output.Attributes.SetAttribute("class", "alert alert-danger");
 var list = new StringBuilder();
 list.Append("<ul class='mb-0'>");
 foreach (var error in errors)
 {
 list.Append($"<li><strong>Error:</strong> {error.ErrorMessage}</li>");
 }
 list.Append("</ul>");
 output.Content.SetHtmlContent(list.ToString());
 }
}

Meilleures pratiques pour construire des aides à l'étiquette

  • Garder la logique C# minimale – Les assistants d'étiquettes sont pour la transformation de la présentation, pas la logique d'affaires.
  • Favor pour I/O – Même si votre implémentation actuelle est synchrone, l'utilisation de facilite l'ajout d'appels asynchrones plus tard sans casser les changements.
  • – Suivez une convention comme ou pour éviter les collisions avec les futures normes HTML.
  • Leverage – Pour les propriétés internes qui ne devraient pas être définies à partir du balisage, marquez-les avec cet attribut.
  • Testez le HTML généré – Écrire des tests d'unité qui incitent l'aideur de tags, invoquent , et vérifiez la sortie en utilisant assertions.
  • Consider accessibilité – Ajouter les attributs ARIA et le support du clavier, le cas échéant.

Pièges et dépannage courants

  • Tag helper not be decouvert – Assurez-vous que la directive dans indique l'ensemble correct. Vérifiez l'espace de noms et le nom de classe.
  • – Utilisez l'attribut pour la carte C# des noms de propriétés aux noms d'attributs HTML. Sans cela, le nom de propriété est utilisé comme tel.
  • Contenu non rendu – Si vous appelez avant de récupérer le contenu de l'enfant, vous perdez le HTML interne original. Appelez toujours en premier si vous en avez besoin.
  • Multiple tag helpers ciblant le même élément – L'ordre d'exécution suit l'ordre alphabétique par défaut, mais peut être contrôlé avec la propriété .
  • Problèmes d'injection de dependency – Les helpers de tag ne sont pas scoped. Si vous injectez un service scoped, assurez-vous que l'aide de tag est consommée dans le même champ de requête HTTP (c'est normalement le cas).

Intégration des aides à l'étiquette personnalisée dans une base de codes existante

Vous pouvez commencer par refactoriser les modèles les plus répétitifs – tels que les boutons, les cartes ou les tables de données – en helpers de tag. Au fil du temps, vous allez construire une bibliothèque qui devient la seule source de vérité pour vos composants d'interface utilisateur. Combinez les helpers de tag avec d'autres outils de composition comme les partiels et les composants de vue pour une flexibilité maximale. Par exemple, un composant de vue peut récupérer des données complexes et ensuite les passer à un helper de tag pour rendre le HTML final.

Ressources externes et lectures complémentaires

Conclusion

Les helpers de tag personnalisés représentent une évolution significative dans la façon dont les développeurs composent les vues dans ASP.NET Core MVC. En vous permettant de définir vos propres éléments HTML et attributs qui exécutent la logique côté serveur, ils comblent l'écart entre le balisage convivial du concepteur et le contrôle programmateur. Des générateurs de boutons simples aux composants complexes et sensibles à l'état qui intègrent l'injection de dépendance, les helpers de tag vous permettent de construire des interfaces utilisateur durables, testables et cohérentes.