Asistentes de etiquetas en ASP.NET Core

Por Rick Anderson

Qué son los asistentes de etiquetas

Las aplicaciones auxiliares de etiquetas permiten que el código de servidor participe en la creación y la representación de elementos HTML en archivos de Razor. Por ejemplo, la aplicación auxiliar ImageTagHelper integrada puede anexar un número de versión al nombre de imagen. Cada vez que la imagen cambia, el servidor genera una nueva versión única para la imagen, lo que garantiza que los clientes puedan obtener la imagen actual (en lugar de una imagen obsoleta almacenada en caché). Hay muchos asistentes de etiquetas integradas para tareas comunes (como la creación de formularios, vínculos, carga de activos, etc.) y existen muchos más a disposición en repositorios públicos de GitHub y como paquetes NuGet. Los asistentes de etiquetas se crean en C# y tienen como destino elementos HTML en función del nombre de elemento, el nombre de atributo o la etiqueta principal. Por ejemplo, la aplicación auxiliar LabelTagHelper integrada puede tener como destino el elemento HTML <label> cuando se aplican atributos LabelTagHelper. Si está familiarizado con los Asistentes de HTML, los asistentes de etiquetas reducen las transiciones explícitas entre HTML y C# en las vistas Razor. En muchos casos, los asistentes de HTML proporcionan un método alternativo para un asistente de etiquetas específico, pero es importante tener en cuenta que los asistentes de etiquetas no reemplazan a los asistentes de HTML y que no hay un asistente de etiquetas para cada asistente de HTML. En Comparación entre los asistentes de etiquetas y los asistentes de HTML se explican las diferencias con más detalle.

Los asistentes de etiquetas no son compatibles con los componentes Razor. Para más información, vea Componentes Razor de ASP.NET Core.

¿Qué proporcionan los asistentes de etiquetas?

Una experiencia de desarrollo amigable con HTML

En su mayor parte, el marcado Razor que utiliza los asistentes de etiquetas tiene el mismo aspecto que el HTML estándar. Los diseñadores de front-end con conocimientos de HTML/CSS/JavaScript pueden editar Razor sin necesidad de aprender Razor sintaxis C#.

Un rico entorno IntelliSense para crear HTML y Razor marcado

Esto contrasta fuertemente con HTML Helpers, el enfoque anterior para la creación del lado del servidor de marcado en vistas Razor. En Comparación entre los asistentes de etiquetas y los asistentes de HTML se explican las diferencias con más detalle. En Compatibilidad de IntelliSense con asistentes de etiquetas se explica el entorno de IntelliSense. Incluso los desarrolladores experimentados con Razor sintaxis C# son más productivos utilizando asistentes de etiquetas que escribiendo código C# Razor.

Una forma de ser más productivo y capaz de producir código más robusto, fiable y mantenible utilizando información solo disponible en el servidor.

Por ejemplo, históricamente el mantra en la actualización de imágenes era cambiar el nombre de la imagen cuando se cambia la imagen. Las imágenes debían almacenarse en caché de forma activa por motivos de rendimiento y, a menos que se cambiase el nombre de una imagen, se corría el riesgo de que los clientes obtuviesen una copia obsoleta. Antes, después de editar una imagen, era necesario cambiarle el nombre y actualizar todas las referencias a la imagen en la aplicación web. Esto no solo es muy laborioso, sino que también es propenso a errores (se podría perder una referencia, introducir accidentalmente la cadena equivocada, etc.) El ImageTagHelper incorporado puede hacer esto por usted automáticamente. ImageTagHelper puede anexar un número de versión al nombre de la imagen, por lo que cada vez que la imagen cambia, el servidor genera automáticamente una nueva versión única de la imagen. Esto garantiza que los clientes obtengan la imagen actual. Esta solidez y ahorro de trabajo se consiguen de forma gratuita mediante el uso de ImageTagHelper.

La mayoría de los asistentes de etiquetas integradas tienen como destino elementos HTML estándar y proporcionan atributos del lado servidor del elemento. Por ejemplo, el elemento <input> que muchas vistas usan en la carpeta Views/Account contiene el atributo asp-for. Este atributo extrae el nombre de la propiedad de modelo especificada en el HTML representado. Considere una vista Razor con el siguiente 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; }
}

El siguiente marcado Razor:

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

Se genera el siguiente código HTML:

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

El atributo asp-for está disponible mediante la propiedad For en LabelTagHelper. Vea Creación de asistentes de etiquetas para más información.

Administración del ámbito de los asistentes de etiquetas

El ámbito de los asistentes de etiquetas se controla mediante una combinación de @addTagHelper, @removeTagHelper y el carácter de exclusión "!".

@addTagHelper hace que los asistentes de etiquetas estén disponibles

Si crea una nueva aplicación web ASP.NET Core llamada AuthoringTagHelpers, se añadirá el siguiente archivo Views/_ViewImports.cshtml a su proyecto:

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

La directiva @addTagHelper hace que los asistentes de etiquetas estén disponibles en la vista. En este caso, el archivo de vista es Pages/_ViewImports.cshtml, que de manera predeterminada es heredado por todos los archivos en la carpeta Pages y subcarpetas; haciendo que los asistentes de etiquetas estén disponibles. El código anterior utiliza la sintaxis comodín ("*") para especificar que todos los asistentes de etiquetas del ensamblado especificado (Microsoft.AspNetCore.Mvc.TagHelpers) estarán disponibles para todos los archivos de vista del directorio o subdirectorio Views. El primer parámetro después de @addTagHelper especifica los asistentes de etiquetas que se van a cargar (usamos "*" para todas los asistentes de etiquetas), y el segundo parámetro ("Microsoft.AspNetCore.Mvc.TagHelpers") especifica el ensamblado que contiene los asistentes de etiquetas. Microsoft.AspNetCore.Mvc.TagHelpers es el ensamblado para los asistentes de etiquetas integradas de ASP.NET Core.

Para exponer todas los asistentes de etiquetas de este proyecto (que crea un ensamblado denominado AuthoringTagHelpers), use lo siguiente:

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

Si el proyecto contiene un asistente EmailTagHelper con el espacio de nombres predeterminado (AuthoringTagHelpers.TagHelpers.EmailTagHelper), puede proporcionar el nombre completo (FQN) del asistente de etiquetas:

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

Para agregar un asistente de etiquetas a una vista con un FQN, agregue primero el FQN (AuthoringTagHelpers.TagHelpers.EmailTagHelper) y, después, el nombre del ensamblado (AuthoringTagHelpers). La mayoría de los desarrolladores prefieren utilizar la sintaxis de carácter comodín "*". La sintaxis carácter comodín permite insertar el carácter comodín "*" como sufijo en un FQN. Por ejemplo, cualquiera de las siguientes directivas incorporará EmailTagHelper:

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

Como se ha mencionado anteriormente, agregar la directiva @addTagHelper al archivo Views/_ViewImports.cshtml hace que el asistente de etiquetas esté disponible para todos los archivos de vista en el directorio Views y subdirectorios. Puede usar la directiva @addTagHelper en archivos de vista específicos si quiere exponer el asistente de etiquetas solo a esas vistas.

@removeTagHelper quita los asistentes de etiquetas

@removeTagHelper tiene los mismos parámetros que @addTagHelper, y quita un asistente de etiquetas que se ha agregado anteriormente. Por ejemplo, si se aplica @removeTagHelper a una vista específica, se quita de la vista el asistente de etiquetas especificada. El uso de @removeTagHelper en un archivo Views/Folder/_ViewImports.cshtml elimina el ayudante de etiquetas especificado de todas las vistas en Carpeta.

Controlar el alcance del asistente de etiquetas con el archivo _ViewImports.cshtml

Puede agregar un _ViewImports.cshtml a cualquier carpeta de vistas, y el motor de vistas aplicará las directivas tanto de ese archivo como del archivo Views/_ViewImports.cshtml. Si agregara un archivo Views/Home/_ViewImports.cshtml vacío para las vistas Home, no habría ningún cambio porque el archivo _ViewImports.cshtml es aditivo. Cualquier directiva @addTagHelper que agregue al archivo Views/Home/_ViewImports.cshtml (que no esté en el archivo Views/_ViewImports.cshtml predeterminado) expondría esos asistentes de etiquetas a las vistas solo en la carpeta Home.

Excluir elementos individuales

Puede deshabilitar un asistente de etiquetas en el nivel de elemento con el carácter de exclusión ("!") del asistente de etiquetas. Por ejemplo, la validación de Email se deshabilita en <span> con el carácter de exclusión del asistente de etiquetas:

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

Debe aplicar el carácter de exclusión del asistente de etiquetas en la etiqueta de apertura y de cierre. (El editor de Visual Studio agrega automáticamente el carácter de exclusión a la etiqueta de cierre cuando se agrega uno a la etiqueta de apertura). Después de agregar el carácter de exclusión, el elemento y los atributos del asistente de etiquetas ya no se muestran en una fuente distinta.

Usar @tagHelperPrefix para hacer explícito el uso del asistente de etiquetas

La directiva @tagHelperPrefix permite especificar una cadena de prefijo de etiqueta para habilitar la compatibilidad con el asistente de etiquetas y hacer explícito su uso. Por ejemplo, podría agregar el siguiente marcado al archivo Views/_ViewImports.cshtml:

@tagHelperPrefix th:

En la imagen de código siguiente, el prefijo del asistente de etiquetas se establece en th:, por lo que solo los elementos con el prefijo th: admiten asistentes de etiquetas (los elementos habilitados para asistentes de etiquetas tienen una fuente distinta). Los elementos <label> y <input> tienen el prefijo de los asistentes de etiquetas y están habilitados para estas, a diferencia del elemento <span>.

Razor markup with Tag Helper prefix set to

Las mismas reglas de jerarquía que se aplican a @addTagHelper también se aplican a @tagHelperPrefix.

Asistentes de etiquetas de autocierre

Muchos asistentes de etiquetas no se pueden usar como etiquetas de autocierre. Algunos asistentes de etiquetas están diseñados para ser etiquetas de cierre. Si se usa un asistente de etiquetas que no se ha diseñado para ser de autocierre se suprime la salida representada. Si se usa el autocierre para un asistente de etiquetas, se genera una etiqueta de autocierre en la salida representada. Vea esta nota en Creación de asistentes de etiquetas para más información.

C# en el atributo/declaración de los asistentes de etiquetas

Los asistentes de etiquetas no admiten C# en el área de declaraciones de etiquetas o atributos del elemento. Por ejemplo, el código siguiente no es válido:

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

El código anterior se puede escribir como:

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

Normalmente, el operador @ inserta una representación textual de una expresión en el marcado HTML renderizado. Sin embargo, cuando una expresión se evalúa como false lógico, el framework elimina el atributo en su lugar. En el ejemplo anterior, el atributo disabled se establece en true si Model o LicenseId es null.

Inicializadores de asistentes de etiquetas

Mientras que los atributos se pueden utilizar para configurar instancias individuales de asistentes de etiquetas, ITagHelperInitializer<TTagHelper> se puede utilizar para configurar todas las instancias de asistentes de etiquetas de un tipo específico. Considera el siguiente ejemplo de un inicializador del asistente de etiquetas que configura el atributo asp-append-version o la propiedad AppendVersion para todas las instancias de ScriptTagHelper en la app:

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

Para utilizar el inicializador, configúrelo registrándolo como parte del inicio de la aplicación:

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

Generación automática de versiones de los asistentes de etiquetas fuera de wwwroot

Para que un asistente de etiquetas genere una versión para un archivo estático fuera de wwwroot, consulte Servir archivos desde varias ubicaciones.

Compatibilidad de IntelliSense con asistentes de etiquetas

Considere la posibilidad de escribir un elemento HTML <label>. En cuanto escriba <l en el editor de Visual Studio, IntelliSense mostrará elementos coincidentes:

After typing

No solo se obtiene la ayuda HTML, sino también el icono (el símbolo "@" con "<>" debajo).

The

El icono identifica el elemento como objetivo de los asistentes de etiquetas. Los elementos HTML puros (como el fieldset) muestran el icono "<>".

Una etiqueta HTML pura <label> muestra la etiqueta HTML (con el tema de color de Visual Studio predeterminado) en una fuente marrón, con los atributos en rojo y los valores de atributo en azul.

Example

Después de escribir <label, IntelliSense muestra los atributos HTML/CSS disponibles y los atributos destinados al asistente de etiquetas:

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

La finalización de instrucciones de IntelliSense permite presionar la tecla TAB para completar la instrucción con el valor seleccionado:

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

En cuanto se especifica un atributo del asistente de etiquetas, las fuentes de las etiquetas y los atributos cambian. Si usa el tema de color predeterminado "Azul" o "Claro" de Visual Studio, la fuente es púrpura en negrita. Si usa el tema "Oscuro", la fuente es verde azulado en negrita. Las imágenes de este documento se han realizado con el tema predeterminado.

The user selected

Puede escribir el atajo CompletarPalabra de Visual Studio (Ctrl +barra espaciadora es el determinado) dentro de las comillas dobles (""), y ahora está en C#, igual que estaría en una clase C#. IntelliSense muestra todos los métodos y propiedades en el modelo de páginas. Los métodos y las propiedades están disponibles porque el tipo de propiedad es ModelExpression. En la imagen siguiente se edita la vista Register, por lo que RegisterViewModel está disponible.

The user types

IntelliSense muestra las propiedades y los métodos disponibles para el modelo en la página. El entorno enriquecido de IntelliSense le ayuda a seleccionar la clase CSS:

The user types

The user types

Comparación entre los asistentes de etiquetas y los asistentes de HTML

Los asistentes de etiquetas se adjuntan a los elementos HTML en las vistas Razor, mientras que los asistentes HTML se invocan como métodos intercalados con HTML en las vistas Razor. Considere el siguiente marcado Razor, que crea una etiqueta HTML con la clase CSS "caption":

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

El símbolo at (@) indica a Razor que éste es el comienzo del código. Los dos parámetros siguientes ("FirstName" y "First Name:") son cadenas, por lo que IntelliSense no sirve de ayuda. El último argumento:

new {@class="caption"}

Es un objeto anónimo que se usa para representar atributos. Dado que class es una palabra clave reservada en C#, use el símbolo @ para forzar a C# a interpretar @class= como un símbolo (nombre de propiedad). Para un diseñador front-end (alguien familiarizado con HTML/CSS/JavaScript y otras tecnologías cliente pero no familiarizado con C# y Razor), la mayor parte de la línea es extraña. Es necesario crear toda la línea sin ayuda de IntelliSense.

Si usa LabelTagHelper, se puede escribir el mismo marcado de la manera siguiente:

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

Con la versión del asistente de etiquetas, en cuanto escriba <l en el editor de Visual Studio, IntelliSense mostrará elementos coincidentes:

The user types

IntelliSense le ayuda a escribir toda la línea.

La siguiente imagen de código muestra la parte del formulario de la vista Views/Account/Register.cshtmlRazor generada a partir de la plantilla ASP.NET 4.5.x MVC incluida con Visual Studio.

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

En el editor de Visual Studio se muestra el código de C# con un fondo gris. Por ejemplo, el asistente de HTML AntiForgeryToken:

@Html.AntiForgeryToken()

Se muestra con un fondo gris. La mayor parte del marcado en la vista de registro es de C#. Compárelo con el método equivalente con asistentes de etiquetas:

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

El marcado es mucho más ordenado y más fácil de leer, modificar y mantener que en el método de asistentes de HTML. El código de C# se reduce a la cantidad mínima que el servidor necesita conocer. En el editor de Visual Studio se muestra el marcado de destino de un asistente de etiquetas en una fuente distinta.

Observe el 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 uno de los atributos "asp-" tiene un valor de "Email", pero "Email" no es una cadena. En este contexto, "Email" es la propiedad de expresión del modelo de C# para RegisterViewModel.

El editor de Visual Studio le ayuda a escribir todo el marcado en el método del asistente de etiquetas del formulario de registro, mientras que Visual Studio no proporciona ninguna ayuda para la mayor parte del código en el método de asistentes de HTML. En Compatibilidad de IntelliSense con asistentes de etiquetas se explica en detalle cómo trabajar con asistentes de etiquetas en el editor de Visual Studio.

Comparación entre los asistentes de etiquetas y los controles de servidor web

  • Los asistentes de etiquetas no poseen el elemento al que están asociadas; simplemente participan en la representación del elemento y el contenido. Los Controles del Servidor Web ASP.NET se declaran e invocan en una página.

  • Los Controles del Servidor Web ASP.NET tienen un ciclo de vida no trivial que puede dificultar el desarrollo y la depuración.

  • Los controles de servidor web permiten agregar funcionalidad a los elementos DOM del cliente mediante un control de cliente. Los asistentes de etiquetas no tienen ningún DOM.

  • Los controles de servidor web incluyen la detección automática del explorador. Los asistentes de etiquetas no tienen conocimiento del explorador.

  • Múltiples asistentes de etiquetas pueden actuar sobre el mismo elemento ( consulte Evitar conflictos entre asistentes de etiquetas), mientras que normalmente no se pueden componer controles de servidor Web.

  • Los asistentes de etiquetas pueden modificar la etiqueta y el contenido de los elementos HTML que tienen como ámbito, pero no modifican directamente ningún otro elemento de una página. Los controles de servidor web tienen un ámbito menos específico y pueden realizar acciones que afectan a otras partes de la página, lo que puede tener efectos secundarios imprevistos.

  • Los controles de servidor web usan convertidores de tipos para convertir cadenas en objetos. Con los asistentes de etiquetas, trabajará de forma nativa en C#, por lo que no necesitará ninguna conversión de tipos.

  • Los controles del Servidor Web utilizan System.ComponentModelpara implementar el comportamiento en tiempo de ejecución y de diseño de los componentes y controles. System.ComponentModel incluye las clases base y las interfaces para implementar atributos y convertidores de tipos, enlazarlos con orígenes de datos y generar licencias para los componentes. Compare esto con los asistentes de etiquetas, que normalmente se derivan de TagHelper, y la clase base TagHelper solo expone dos métodos, Process y ProcessAsync.

Personalizar la fuente de elemento de asistentes de etiquetas

Puede personalizar la fuente y el color en Herramientas>Opciones>Entorno>Fuentes y colores:

Options dialog in Visual Studio

Asistentes de etiquetas integradas de ASP.NET Core

Anchor

Cache

Componente

Caché distribuida

Entorno

Forma

Acción de formulario

Imagen

Entrada

Etiqueta

Vínculo

Parcial

Conservar estado del componente

Script

Seleccionar

Textarea

Mensaje de validación

Resumen de validación

Recursos adicionales