Auxiliares de Marca no ASP.NET Core

De Rick Anderson

O que são Auxiliares de Marca

Os Auxiliares de Marcação permitem que o código do servidor participe da criação e renderização de elementos HTML em arquivos do Razor. Por exemplo, o ImageTagHelper interno pode acrescentar um número de versão ao nome da imagem. Sempre que a imagem é alterada, o servidor gera uma nova versão exclusiva para a imagem, de modo que os clientes tenham a garantia de obter a imagem atual (em vez de uma imagem obsoleta armazenada em cache). Há muitos Auxiliares de Marca internos para tarefas comuns – como criação de formulários, links, carregamento de ativos e muito mais – e ainda outros disponíveis em repositórios GitHub públicos e como NuGet. Os Auxiliares de Marca são criados no C# e são direcionados a elementos HTML de acordo com o nome do elemento, o nome do atributo ou a marca pai. Por exemplo, o LabelTagHelper interno pode ser direcionado ao elemento <label> HTML quando os atributos LabelTagHelper são aplicados. Se você está familiarizado com Auxiliares de HTML, os Auxiliares de Marca reduzem as transições explícitas entre HTML e C# em modos de exibição do Razor. Em muitos casos, os Auxiliares HTML fornecem uma abordagem alternativa a um Auxiliar de Marca específico, mas é importante reconhecer que os Auxiliares de Marca não substituem os Auxiliares HTML e que não há um Auxiliar de Marca para cada Auxiliar HTML. Comparação entre Auxiliares de Marca e Auxiliares HTML explica as diferenças mais detalhadamente.

Os Auxiliares de Marca não são compatíveis com componentes Razor. Para saber mais, confira Componentes Razor do ASP.NET Core.

O que os Auxiliares de Marca fornecem

Uma experiência de desenvolvimento amigável a HTML

Na maioria das vezes, a marcação Razor usando Auxiliares de Marca se parece com HTML padrão. Designers de front-end familiarizados com HTML/CSS/JavaScript podem editar o Razor sem aprender a sintaxe Razor do C#.

Um ambiente avançado do IntelliSense para criar HTML e Razormarcação

Isso contrasta fortemente com os Auxiliares de HTML, a abordagem anterior para a criação de marcações no lado do servidor em modos de exibição do Razor. Comparação entre Auxiliares de Marca e Auxiliares HTML explica as diferenças mais detalhadamente. Suporte do IntelliSense para Auxiliares de Marca explica o ambiente do IntelliSense. Até mesmo desenvolvedores experientes com a sintaxe C# do Razor são mais produtivos usando Auxiliares de Marca do que escrevendo a marcação Razor do C#.

Uma maneira de torná-lo mais produtivo e capaz de produzir códigos mais robustos, confiáveis e de fácil manutenção usando informações disponíveis apenas no servidor

Por exemplo, historicamente, o mantra na atualização de imagens era alterar o nome da imagem quando você altera a imagem. As imagens devem ser armazenadas em cache de forma agressiva por motivos de desempenho e, a menos que você altere o nome de uma imagem, você corre o risco de os clientes obterem uma cópia obsoleta. Historicamente, depois que uma imagem era editada, o nome precisava ser alterado e cada referência à imagem no aplicativo Web precisava ser atualizada. Isso não é apenas muito trabalhoso, mas também sujeito a erros (você pode perder uma referência, inserir acidentalmente a cadeia de caracteres errada, etc.) O ImageTagHelper interno pode fazer isso para você automaticamente. O ImageTagHelper pode acrescentar um número de versão ao nome da imagem, de modo que sempre que a imagem é alterada, o servidor gera automaticamente uma nova versão exclusiva para a imagem. Os clientes têm a garantia de obter a imagem atual. Basicamente, essa economia na robustez e no trabalho é obtida gratuitamente com o ImageTagHelper.

A maioria dos auxiliares de marca internos é direcionada a elementos HTML padrão e fornece atributos do lado do servidor para o elemento. Por exemplo, o elemento <input> usado em várias exibições na pasta Exibição/Conta contém o atributo asp-for. Esse atributo extrai o nome da propriedade do modelo especificado no HTML renderizado. Considere um modo de exibição do Razor com o seguinte modelo:

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; }
}

A seguinte marcação do Razor:

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

Gera o seguinte HTML:

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

O atributo asp-for é disponibilizado pela propriedade For no LabelTagHelper. Confira Auxiliares de marca de autor para obter mais informações.

Gerenciando o escopo do Auxiliar de Marca

O escopo dos Auxiliares de Marca é controlado por uma combinação de @addTagHelper, @removeTagHelper e o caractere de recusa "!".

@addTagHelper disponibiliza os Auxiliares de Marca

Se você criar um novo aplicativo Web ASP.NET Core chamado AuthoringTagHelpers, o seguinte arquivo Views/_ViewImports.cshtml será adicionado ao projeto:

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

A diretiva @addTagHelper disponibiliza os Auxiliares de Marca para a exibição. Nesse caso, o arquivo de exibição é Pages/_ViewImports.cshtml, que é herdado por padrão por todos os arquivos na pasta Páginas e suas subpastas, disponibilizando os Auxiliares de Marca. O código acima usa a sintaxe curinga ("*") para especificar que todos os Auxiliares de Marca no assembly especificado (Microsoft.AspNetCore.Mvc.TagHelpers) estarão disponíveis para todos os arquivos de exibição no diretório ou subdiretório Modos de Exibição. O primeiro parâmetro após @addTagHelper especifica os Auxiliares de Marca a serem carregados (estamos usando "*" para todos os Auxiliares de Marca) e o segundo parâmetro "Microsoft.AspNetCore.Mvc.TagHelpers" especifica o assembly que contém os Auxiliares de Marca. Microsoft.AspNetCore.Mvc.TagHelpers é o assembly para os Auxiliares de Marca internos do ASP.NET Core.

Para expor todos os Auxiliares de Marca neste projeto (que cria um assembly chamado AuthoringTagHelpers), você usará o seguinte:

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

Se o projeto contém um EmailTagHelper com o namespace padrão (AuthoringTagHelpers.TagHelpers.EmailTagHelper), forneça o FQN ( nome totalmente qualificado) do Auxiliar de Marca:

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

Para adicionar um Auxiliar de Marca a uma exibição usando um FQN, primeiro adicione o FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper) e, em seguida, o nome do assembly (AuthoringTagHelpers). A maioria dos desenvolvedores prefere usar a sintaxe curinga "*". A sintaxe curinga permite que você insira o caractere curinga "*" como o sufixo de um FQN. Por exemplo, uma das seguintes diretivas exibirá o EmailTagHelper:

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

Conforme mencionado anteriormente, a adição da diretiva @addTagHelper ao arquivo Views/_ViewImports.cshtml disponibiliza o Auxiliar de Marca para todos os arquivos de exibição no diretório e subdiretórios Modos de Exibição. Use a diretiva @addTagHelper nos arquivos de exibição específicos se você deseja aceitar a exposição do Auxiliar de Marca a apenas essas exibições.

@removeTagHelper remove os Auxiliares de Marca

O @removeTagHelper tem os mesmos dois parâmetros @addTagHelper e remove um Auxiliar de Marca adicionado anteriormente. Por exemplo, @removeTagHelper aplicado a uma exibição específica remove o Auxiliar de Marca especificado da exibição. O uso de @removeTagHelper em um arquivo Views/Folder/_ViewImports.cshtml remove o Auxiliar de Marca especificado de todas as exibições na Pasta.

Como controlando o escopo do Auxiliar de Marca com o arquivo _ViewImports.cshtml

Você pode adicionar um _ViewImports.cshtml a qualquer pasta de exibição e o mecanismo de exibição aplica as diretivas desse arquivo e do arquivo Views/_ViewImports.cshtml. Se você adicionou um arquivo Views/Home/_ViewImports.cshtml vazio para os modos de exibição Home, não haverá alteração porque o arquivo _ViewImports.cshtml é aditivo. Quaisquer diretivas @addTagHelper que você adicionar ao arquivo Views/Home/_ViewImports.cshtml (que não estejam no arquivo Views/_ViewImports.cshtml padrão) exporiam esses Auxiliares de Marca a exibições apenas na pasta Home.

Recusando elementos individuais

Desabilite um Auxiliar de Marca no nível do elemento com o caractere de recusa do Auxiliar de Marca ("!"). Por exemplo, a validação Email está desabilitada no <span> com o caractere de recusa do Auxiliar de Marca:

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

É necessário aplicar o caractere de recusa do Auxiliar de Marca à marca de abertura e fechamento. (O editor do Visual Studio adiciona automaticamente o caractere de recusa à marca de fechamento quando um é adicionado à marca de abertura). Depois de adicionar o caractere de recusa, o elemento e os atributos do Auxiliar de Marca deixam de ser exibidos em uma fonte diferenciada.

Usando @tagHelperPrefix para tornar explícito o uso do Auxiliar de Marca

A diretiva @tagHelperPrefix permite que você especifique uma cadeia de caracteres de prefixo de marca para habilitar o suporte do Auxiliar de Marca e tornar explícito o uso do Auxiliar de Marca. Por exemplo, você pode adicionar a seguinte marcação ao arquivo Views/_ViewImports.cshtml:

@tagHelperPrefix th:

Na imagem do código abaixo, o prefixo do Auxiliar de Marca é definido como th:; portanto, somente esses elementos que usam o prefixo th: dão suporte a Auxiliares de Marca (elementos habilitados para Auxiliar de Marca têm uma fonte diferenciada). Os elementos <label> e <input> têm o prefixo do Auxiliar de Marca e são habilitados para Auxiliar de Marca, ao contrário do elemento <span>.

Razor markup with Tag Helper prefix set to

As mesmas regras de hierarquia que se aplicam a @addTagHelper também se aplicam a @tagHelperPrefix.

Auxiliares de Marca com autofechamento

Muitos Auxiliares de Marca não podem ser usados como marcações com autofechamento. Alguns Auxiliares de Marca são projetados para serem marcações com autofechamento. Usar um Auxiliar de Marca que não foi projetado para ser de autofechamento suprime a saída renderizada. Um Auxiliar de Marca com autofechamento resulta em uma marca com autofechamento na saída renderizada. Para obter mais informações, confira esta observação em Criando Auxiliares de Marca.

C# no atributo/declaração Auxiliares de Marca

Os Auxiliares de Marca não permitem C# na área de declaração de atributo ou marca do elemento. Por exemplo, o seguinte código não é compatível:

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

O código anterior pode ser gravado como:

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

Normalmente, o operador @ insere uma representação textual de uma expressão na marcação HTML renderizada. No entanto, quando uma expressão é avaliada como false lógica, a estrutura remove o atributo. No exemplo anterior, o atributo disabled será definido como truese Model ou LicenseId for null.

Inicializadores do Auxiliar de marca

Embora os atributos possam ser usados para configurar instâncias individuais de auxiliares de marca, ITagHelperInitializer<TTagHelper> podem ser usados para configurar todas as instâncias auxiliares de marca de um tipo específico. Considere o seguinte exemplo de um inicializador auxiliar de marca que configura o atributo asp-append-version ou a propriedade AppendVersion para todas as instâncias de ScriptTagHelper no aplicativo:

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

Para usar o inicializador, configure-o registrando-o como parte da inicialização do aplicativo:

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

Geração automática de versão do Auxiliar de Marca fora do wwwroot

Para que um Auxiliar de Marca gere uma versão para um arquivo estático fora de wwwroot, consulte Servir arquivos de vários locais

Suporte do IntelliSense para Auxiliares de Marca

Considere a escrita de um elemento <label> HTML. Assim que você insere <l no editor do Visual Studio, o IntelliSense exibe elementos correspondentes:

After typing

Você obtém a ajuda do HTML e também o ícone (o símbolo de "@" com "<>" abaixo dele).

The

identifica o elemento como direcionado a Auxiliares de Marca. Elementos HTML puros (como o fieldset) exibem o ícone "<>".

Uma marca <label> HTML pura exibe a marca HTML (com o tema de cores padrão do Visual Studio) em uma fonte marrom, os atributos em vermelho e os valores de atributo em azul.

Example

Depois de inserir <label, o IntelliSense lista os atributos HTML/CSS disponíveis e os atributos direcionados ao Auxiliar de Marca:

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

O preenchimento de declaração do IntelliSense permite que você pressione a tecla TAB para preencher a declaração com o valor selecionado:

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

Assim que um atributo do Auxiliar de Marca é inserido, as fontes da marca e do atributo são alteradas. Usando o tema de cores padrão "Azul" ou "Claro" do Visual Studio, a fonte é roxo em negrito. Se estiver usando o tema "Escuro", a fonte será azul-petróleo em negrito. As imagens deste documento foram obtidas usando o tema padrão.

The user selected

Você pode inserir o atalho do Visual Studio CompleteWord (Ctrl +barra de espaço é o padrão) entre aspas duplas ("") e agora estará em C#, exatamente como estaria em uma classe C#. O IntelliSense exibe todos os métodos e propriedades no modelo de página. Os métodos e as propriedades estão disponíveis porque o tipo de propriedade é ModelExpression. Na imagem abaixo, estou editando a exibição Register e, portanto, o RegisterViewModel está disponível.

The user types

O IntelliSense lista as propriedades e os métodos disponíveis para o modelo na página. O ambiente avançado de IntelliSense ajuda você a selecionar a classe CSS:

The user types

The user types

Comparação entre Auxiliares de Marca e Auxiliares HTML

Auxiliares de marca são anexados a elementos HTML em modos de exibição do Razor, enquanto os Auxiliares de HTML são invocados como métodos intercalados com HTML em modos de exibição do Razor. Considere a seguinte marcação do Razor, que cria um rótulo HTML com a classe CSS "caption":

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

O símbolo de arroba (@) informa o Razor de que esse é o início do código. Os dois próximos parâmetros ("FirstName" e "First Name:") são cadeias de caracteres; portanto, o IntelliSense não pode ajudar. O último argumento:

new {@class="caption"}

É um objeto anônimo usado para representar atributos. Como a class é uma palavra-chave reservada no C#, use o símbolo @ para forçar o C# a interpretar @class= como um símbolo (nome da propriedade). Para um designer de front-end (alguém familiarizado com HTML/CSS/JavaScript e outras tecnologias de cliente, mas não familiarizado com o C# e Razor), a maior parte da linha é estranha. Toda a linha precisa ser criada sem nenhuma ajuda do IntelliSense.

Usando o LabelTagHelper, a mesma marcação pode ser escrita como:

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

Com a versão do Auxiliar de Marca, assim que você insere <l no editor do Visual Studio, o IntelliSense exibe elementos correspondentes:

The user types

O IntelliSense ajuda você a escrever a linha inteira.

A imagem de código a seguir mostra a parte de Formulário do modo de exibição Views/Account/Register.cshtmlRazor gerada a partir do modelo ASP.NET 4.5.x MVC incluído no Visual Studio.

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

O editor do Visual Studio exibe o código C# com uma tela de fundo cinza. Por exemplo, o Auxiliar HTML AntiForgeryToken:

@Html.AntiForgeryToken()

é exibido com uma tela de fundo cinza. A maior parte da marcação na exibição Register é C#. Compare isso com a abordagem equivalente ao uso de Auxiliares de Marca:

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

A marcação é muito mias limpa e fácil de ler, editar e manter que a abordagem dos Auxiliares HTML. O código C# é reduzido ao mínimo que o servidor precisa conhecer. O editor do Visual Studio exibe a marcação direcionada por um Auxiliar de Marca em uma fonte diferenciada.

Considere o grupo 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>

Cada um dos atributos "asp-" tem um valor "Email", mas "Email" não é uma cadeia de caracteres. Nesse contexto, "Email" é a propriedade da expressão do modelo C# para o RegisterViewModel.

O editor do Visual Studio ajuda você a escrever toda a marcação na abordagem do Auxiliar de Marca de formulário de registro, enquanto o Visual Studio não fornece nenhuma ajuda para a maioria do código na abordagem de Auxiliares HTML. Suporte do IntelliSense para Auxiliares de Marca apresenta detalhes sobre como trabalhar com Auxiliares de Marca no editor do Visual Studio.

Comparação entre Auxiliares de Marca e Controles de Servidor Web

  • Os Auxiliares de Marca não têm o elemento ao qual estão associados; simplesmente participam da renderização do elemento e do conteúdo. Os controles de servidor Web ASP.NET são declarados e invocados em uma página.

  • Os Controles do Servidor Web do ASP.NET têm um ciclo de vida não trivial que pode dificultar o desenvolvimento e a depuração.

  • Os controles do Servidor Web permitem que você adicione a funcionalidade aos elementos DOM (Modelo de Objeto do Documento) do cliente por meio de um controle de cliente. Os Auxiliares de Marca não tem nenhum DOM.

  • Os controles de Servidor Web incluem a detecção automática do navegador. Os Auxiliares de Marca não têm nenhum conhecimento sobre o navegador.

  • Vários Auxiliares de Marca podem atuar no mesmo elemento (consulte Como evitar conflitos do Auxiliar de Marca), embora normalmente não seja possível compor controles de Servidor Web.

  • Os Auxiliares de Marca podem modificar a marca e o conteúdo de elementos HTML no escopo com o qual foram definidos, mas não modificam diretamente todo o resto em uma página. Os controles de Servidor Web têm um escopo menos específico e podem executar ações que afetam outras partes da página, permitindo efeitos colaterais não intencionais.

  • Os controles de Servidor Web usam conversores de tipo para converter cadeias de caracteres em objetos. Com os Auxiliares de Marca, você trabalha nativamente no C# e, portanto, não precisa fazer a conversão de tipo.

  • Os controles de Servidor Web usam System.ComponentModel para implementar o comportamento de componentes e controles em tempo de execução e em tempo de design. System.ComponentModel inclui as interfaces e as classes base para implementar atributos e conversores de tipo, associar a fontes de dados e licenciar componentes. Compare isso com os Auxiliares de Marca, que normalmente são derivados de TagHelper, e a classe base TagHelper expõe apenas dois métodos, Process e ProcessAsync.

Personalizando a fonte de elemento do Auxiliar de Marca

Personalize a fonte e a colorização em Ferramentas>Opções>Ambiente>Fontes e Cores:

Options dialog in Visual Studio

Auxiliares de marcação internos do ASP.NET Core

Âncora

Cache

Componente

Cache distribuído

Ambiente

Formulário

Ação de formulário

Imagem

Entrada

Rótulo

Link

Parcial

Persistir o estado do componente

Script

Selecionar

Textarea

Mensagem de validação

Resumo de validação

Recursos adicionais