Tag Helper Components dans ASP.NET Core
Par Scott Addie et Fiyaz Bin Hasan
Un Tag Helper Component est un Tag Helper qui vous permet de modifier ou d’ajouter des éléments HTML de manière conditionnelle à partir du code côté serveur. Cette fonctionnalité est disponible dans ASP.NET Core 2.0 ou version ultérieure.
ASP.NET Core inclut deux Tag Helper Components intégrés : head
et body
. Ils se trouvent dans l’espace de noms Microsoft.AspNetCore.Mvc.Razor.TagHelpers et peuvent être utilisés dans des pages MVC et Razor. Les composants de Tag Helper ne nécessitent pas d’inscription avec l’application dans _ViewImports.cshtml
.
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
Cas d'utilisation
Voici deux cas d’usage courants des Tag Helper Components :
Les sections suivantes décrivent ces cas d’usage.
Injection dans l’élément head HTML
Dans l’élément <head>
HTML, les fichiers CSS sont généralement importés avec l’élément <link>
HTML. Le code suivant injecte un élément <link>
dans l’élément <head>
à l’aide du Tag Helper Component head
:
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;
}
}
}
Dans le code précédent :
- L'objet
AddressStyleTagHelperComponent
implémente l'objet TagHelperComponent. L’abstraction :- Permet l’initialisation de la classe avec un TagHelperContext.
- Permet l’utilisation des Tag Helper Components pour ajouter ou modifier des éléments HTML.
- La propriété Order définit l’ordre dans lequel les Components sont rendus.
Order
est requis quand il y a plusieurs utilisations des Tag Helper Components dans une application. - ProcessAsync compare la valeur de la propriété TagName du contexte d’exécution à
head
. Si le résultat de la comparaison est true, le contenu du champ_style
est injecté dans l’élément<head>
HTML.
Injection dans l’élément body HTML
Le Tag Helper Component body
peut injecter un élément <script>
dans l’élément <body>
. Le code suivant illustre cette technique :
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);
}
}
}
}
Un fichier HTML distinct est utilisé pour stocker l’élément <script>
. Le fichier HTML rend le code plus lisible et plus facile à tenir à jour. Le code précédent lit le contenu de TagHelpers/Templates/AddressToolTipScript.html
et l’ajoute à la sortie du Tag Helper. Le fichier AddressToolTipScript.html
contient le balisage suivant :
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
Le code précédent lie un widget tooltip amorçable à tout élément <address>
contenant un attribut printable
. L’effet est visible quand l’utilisateur pointe sur l’élément avec la souris.
Inscrire un Component
Un Tag Helper Component doit être ajouté à la collection des Tag Helper Components de l’application. Cet ajout à la collection peut s’effectuer de trois façons :
- Inscription par le biais d’un conteneur de services
- Inscription au moyen d’un fichier Razor
- Inscription à l’aide d’un modèle de page ou d’un contrôleur
Inscription par le biais d’un conteneur de services
Si la classe Tag Helper Component n’est pas managée avec ITagHelperComponentManager, elle doit être inscrite avec le système d’injection de dépendances. Le code Startup.ConfigureServices
ci-dessous inscrit les classes AddressStyleTagHelperComponent
et AddressScriptTagHelperComponent
avec une durée de vie transitoire (transient) :
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>();
}
Inscription au moyen d’un fichier Razor
Si le composant de Tag Helper n’est pas inscrit avec le système d’injection de dépendances, il peut être inscrit depuis une page Razor ou une vue MVC. Cette technique permet de contrôler le balisage injecté et l’ordre d’exécution des composants à partir d’un fichier Razor.
ITagHelperComponentManager
est utilisé pour ajouter ou supprimer des Tag Helper Components dans l’application. Le code suivant illustre cette technique avec AddressTagHelperComponent
:
@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));
}
Dans le code précédent :
- La directive
@inject
fournit une instance deITagHelperComponentManager
. L’instance est assignée à une variable nomméemanager
pour l’accès en aval dans le fichier Razor. - Une instance de
AddressTagHelperComponent
est ajoutée à la collection des Tag Helper Components de l’application.
AddressTagHelperComponent
est modifié pour contenir un constructeur qui accepte les paramètres markup
et order
:
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
Voici comment le paramètre markup
s’utilise dans ProcessAsync
:
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}");
}
}
Inscription à l’aide d’un modèle de page ou d’un contrôleur
Si le composant de Tag Helper n’est pas inscrit avec le système d’injection de dépendances, il peut être inscrit à partir d’un modèle de page Razor ou d’un contrôleur MVC. Cette technique est utile pour séparer la logique C# des fichiers Razor.
L’injection de constructeur est utilisée pour accéder à une instance de ITagHelperComponentManager
. Le Tag Helper Component est ajouté à la collection des Tag Helper Components de l’instance. Le modèle de page Razor ci-dessous illustre cette technique avec 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));
}
}
Dans le code précédent :
- L’injection de constructeur est utilisée pour accéder à une instance de
ITagHelperComponentManager
. - Une instance de
AddressTagHelperComponent
est ajoutée à la collection des Tag Helper Components de l’application.
Créer un Component
Pour créer un Tag Helper Component personnalisé :
- Créez une classe publique dérivée de TagHelperComponentTagHelper.
- Appliquez un attribut
[HtmlTargetElement]
à la classe. Spécifiez le nom de l’élément HTML cible. - Facultatif : appliquez un attribut
[EditorBrowsable(EditorBrowsableState.Never)]
à la classe pour supprimer l’affichage de type dans IntelliSense.
Le code suivant crée un Tag Helper Component personnalisé qui cible l’élément HTML <address>
:
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)
{
}
}
}
Utilisez le Tag Helper Component address
personnalisé pour injecter le balisage HTML comme ceci :
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}");
}
}
}
La méthode ProcessAsync
précédente injecte le code HTML fourni à SetHtmlContent dans l’élément <address>
correspondant. L’injection se produit quand :
- La propriété
TagName
du contexte d’exécution a la valeuraddress
. - L’élément
<address>
correspondant a un attributprintable
.
Par exemple, l’instruction if
a la valeur true quand l’élément <address>
suivant est exécuté :
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
Ressources supplémentaires
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour