Componentes do Auxiliar de Marca no ASP.NET Core
Por Scott Addie e Fiyaz Bin Hasan
Um Componente do Auxiliar de Marca é um Auxiliar de Marca que permite que você modifique ou adicione condicionalmente elementos HTML de código do lado do servidor. Esse recurso está disponível no ASP.NET Core 2.0 ou posterior.
O ASP.NET Core inclui dois Componentes de Auxiliar de Marca internos: head
e body
. Eles estão localizados no namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers e pode ser usados no MVC e no Razor Pages. Componentes do Auxiliar de Marca não requerem registro com o aplicativo em _ViewImports.cshtml
.
Exibir ou baixar código de exemplo (como baixar)
Casos de uso
Dois casos de uso comum dos Componentes do Auxiliar de Marca incluem:
As seções a seguir descrevem esses casos de uso.
Injetar no elemento HTML head
Dentro do elemento HTML <head>
, os arquivos CSS são geralmente importados com o elemento HTML <link>
. O código a seguir injeta um elemento <link>
no elemento <head>
usando o Componente do Auxiliar de Marca 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;
}
}
}
No código anterior:
AddressStyleTagHelperComponent
implementa TagHelperComponent. A abstração:- Permite a inicialização da classe com um TagHelperContext.
- Habilita o uso de Componentes do Auxiliar de Marca para adicionar ou modificar elementos HTML.
- A propriedade Order define a ordem na qual os Componentes são renderizados.
Order
é necessário quando há vários usos de Componentes do Auxiliar de Marca em um aplicativo. - ProcessAsync compara o valor da propriedade TagName do contexto de execução com
head
. Se a comparação for avaliada como verdadeira, o conteúdo do campo_style
será injetado no elemento HTML<head>
.
Injetar no elemento HTML body
O Componente do Auxiliar de Marca body
pode injetar um elemento <script>
no elemento <body>
. O código a seguir demonstra essa técnica:
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);
}
}
}
}
Um arquivo HTML separado é usado para armazenar o elemento <script>
. O arquivo HTML torna o código mais limpo e mais sustentável. O código anterior lê o conteúdo de TagHelpers/Templates/AddressToolTipScript.html
e acrescenta-o com a saída do Auxiliar de Marca. O arquivo AddressToolTipScript.html
inclui a seguinte marcação:
<script>
$("address[printable]").hover(function() {
$(this).attr({
"data-toggle": "tooltip",
"data-placement": "right",
"title": "Home of Microsoft!"
});
});
</script>
O código anterior associa um widget de Dica de ferramenta de inicialização a qualquer elemento <address>
que inclua um atributo printable
. O efeito é visível quando um ponteiro do mouse focaliza o elemento.
Registrar um componente
Um Componente do Auxiliar de Marca precisa ser adicionado à coleção de Componentes do Auxiliar de Marca do aplicativo. Há três maneiras de adicioná-lo à coleção:
- Registro por contêiner de serviços
- Registro por arquivo Razor
- Registro por Modelo de página ou controlador
Registro por contêiner de serviços
Se a classe do Componente do Auxiliar de Marca não for gerenciada com ITagHelperComponentManager, ela precisará ser registrada com o sistema de DI (injeção de dependência). O código Startup.ConfigureServices
a seguir registra as classes AddressStyleTagHelperComponent
e AddressScriptTagHelperComponent
com um tempo de vida transitório:
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>();
}
Registro por arquivo Razor
Se o Componente do Auxiliar de Marca não estiver registrado com DI, ele poderá ser registrado por uma página do Razor Pages ou uma exibição do MVC. Essa técnica é usada para controlar a marcação injetada e o pedido de execução do componente de um arquivo Razor.
ITagHelperComponentManager
é usado para adicionar Componentes do Auxiliar de Marca ou removê-los do aplicativo. O código a seguir demonstra essa técnica com 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));
}
No código anterior:
- A diretiva
@inject
fornece uma instância deITagHelperComponentManager
. A instância é atribuída a uma variável chamadamanager
para acesso downstream no arquivo Razor. - Uma instância do
AddressTagHelperComponent
é adicionada à coleção de Componentes do Auxiliar de Marca do aplicativo.
AddressTagHelperComponent
é modificado para acomodar um construtor que aceita os parâmetros markup
e order
:
private readonly string _markup;
public override int Order { get; }
public AddressTagHelperComponent(string markup = "", int order = 1)
{
_markup = markup;
Order = order;
}
O parâmetro markup
fornecido é usado em ProcessAsync
da seguinte maneira:
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}");
}
}
Registro por Modelo de página ou controlador
Se o Componente do Auxiliar de Marca não estiver registrado com DI, ele poderá ser registrado por um modelo de página do Razor Pages ou um controlador MVC. Essa técnica é útil para separar a lógica C# de arquivos Razor.
A injeção do construtor é usada para acessar uma instância de ITagHelperComponentManager
. Um Componente do Auxiliar de Marca é adicionado à coleção de Componentes do Auxiliar de Marca da instância. O modelo de página do Razor Pages a seguir demonstra essa técnica com 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));
}
}
No código anterior:
- A injeção do construtor é usada para acessar uma instância de
ITagHelperComponentManager
. - Uma instância do
AddressTagHelperComponent
é adicionada à coleção de Componentes do Auxiliar de Marca do aplicativo.
Criar um componente
Para criar um Componente do Auxiliar de Marca personalizado:
- Crie uma classe pública derivada de TagHelperComponentTagHelper.
- Aplique um atributo
[HtmlTargetElement]
à classe. Especifique o nome do elemento HTML de destino. - Opcional: aplique um atributo
[EditorBrowsable(EditorBrowsableState.Never)]
à classe para suprimir a exibição do tipo no IntelliSense.
O código a seguir cria um Componente do Auxiliar de Marca personalizado que tem como destino o elemento 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)
{
}
}
}
Usar o Componente do Auxiliar de Marca address
personalizado para inserir uma marcação HTML da seguinte maneira:
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}");
}
}
}
O método ProcessAsync
anterior injeta o HTML fornecido para SetHtmlContent no elemento <address>
correspondente. A injeção ocorre quando:
- O valor da propriedade
TagName
do contexto de execução é igual aaddress
. - O elemento
<address>
correspondente tem um atributoprintable
.
Por exemplo, a instrução if
é avaliada como verdadeira ao processar o seguinte elemento <address>
:
<address printable>
One Microsoft Way<br />
Redmond, WA 98052-6399<br />
<abbr title="Phone">P:</abbr>
425.555.0100
</address>
Recursos adicionais
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de