Asistente de etiquetas delimitadoras en ASP.NET Core

De Peter Kellner y Scott Addie

El asistente de etiquetas delimitadoras mejora la etiqueta delimitadora de código HTML estándar (<a ... ></a>) agregando nuevos atributos. Por convención, los nombres de atributo tienen el prefijo asp-. El valor de atributo href del elemento delimitador representado se determina mediante los valores de los atributos asp-.

Para obtener información general sobre los asistentes de etiquetas, consulte Asistentes de etiquetas en ASP.NET Core.

Vea o descargue el código de ejemplo (cómo descargarlo)

En los ejemplos de todo este documento se usa SpeakerController:

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;

public class SpeakerController : Controller
{
    private List<Speaker> Speakers =
        new List<Speaker>
        {
            new Speaker {SpeakerId = 10},
            new Speaker {SpeakerId = 11},
            new Speaker {SpeakerId = 12}
        };

    [Route("Speaker/{id:int}")]
    public IActionResult Detail(int id) =>
        View(Speakers.FirstOrDefault(a => a.SpeakerId == id));

    [Route("/Speaker/Evaluations", 
           Name = "speakerevals")]
    public IActionResult Evaluations() => View();

    [Route("/Speaker/EvaluationsCurrent",
           Name = "speakerevalscurrent")]
    public IActionResult Evaluations(
        int speakerId,
        bool currentYear) => View();

    public IActionResult Index() => View(Speakers);
}

public class Speaker
{
    public int SpeakerId { get; set; }
}

Atributos del asistente de etiquetas delimitadoras

asp-controller

El atributo asp-controller asigna el controlador usado para generar la dirección URL. En el marcado siguiente se especifican todos los altavoces:

<a asp-controller="Speaker"
   asp-action="Index">All Speakers</a>

El código HTML generado:

<a href="/Speaker">All Speakers</a>

Si el atributo asp-controller está especificado y asp-action no lo está, el valor asp-action predeterminado es la acción del controlador asociada a la vista que se está ejecutando. Si se omite asp-action en el marcado anterior y se usa el asistente de etiquetas delimitadoras en la vista Índice del HomeControlador (/Home), el código HTML generado es el siguiente:

<a href="/Home">All Speakers</a>

asp-action

El valor del atributo asp-action representa el nombre de la acción del controlador incluido en el atributo href generado. El siguiente marcado establece el valor del atributo href generado en la página "Speaker Evaluations":

<a asp-controller="Speaker"
   asp-action="Evaluations">Speaker Evaluations</a>

El código HTML generado:

<a href="/Speaker/Evaluations">Speaker Evaluations</a>

Si no hay ningún atributo asp-controller especificado, se usará el controlador predeterminado que llama a la vista que se está ejecutando.

Si el valor del atributo asp-action es Index, no se anexa ninguna acción a la dirección URL, lo que da lugar a la invocación de la acción Index predeterminada. La acción especificada (o su valor predeterminado), debe existir en el controlador al que se hace referencia en asp-controller.

asp-route-{valor}

El atributo asp-route-{value} permite indicar un prefijo de ruta comodín. Cualquier valor que ocupe el marcador de posición {value} se interpretará como un parámetro de ruta potencial. Si no se encuentra ninguna ruta predeterminada, este prefijo de ruta se anexará al atributo href generado como valor y parámetro de solicitud. En caso contrario, se sustituirá en la plantilla de ruta.

Observe la siguiente acción del controlador:

private List<Speaker> Speakers =
    new List<Speaker>
    {
        new Speaker {SpeakerId = 10},
        new Speaker {SpeakerId = 11},
        new Speaker {SpeakerId = 12}
    };

[Route("Speaker/{id:int}")]
public IActionResult Detail(int id) =>
    View(Speakers.FirstOrDefault(a => a.SpeakerId == id));

Con una plantilla de ruta predeterminada definida en Startup.Configure:

app.UseMvc(routes =>
{
    // need route and attribute on controller: [Area("Blogs")]
    routes.MapRoute(name: "mvcAreaRoute",
                    template: "{area:exists}/{controller=Home}/{action=Index}");

    // default route for non-areas
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

La vista de MVC usa el modelo, proporcionado por la acción, como se indica a continuación:

@model Speaker
<!DOCTYPE html>
<html>
<body>
    <a asp-controller="Speaker"
       asp-action="Detail" 
       asp-route-id="@Model.SpeakerId">SpeakerId: @Model.SpeakerId</a>
</body>
</html>

Se hace coincidir el marcador de posición {id?} de la ruta predeterminada. El código HTML generado:

<a href="/Speaker/Detail/12">SpeakerId: 12</a>

Supongamos que el prefijo de ruta no forma parte de la plantilla de enrutamiento coincidente, al igual que con la siguiente vista de MVC:

@model Speaker
<!DOCTYPE html>
<html>
<body>
    <a asp-controller="Speaker"
       asp-action="Detail"
       asp-route-speakerid="@Model.SpeakerId">SpeakerId: @Model.SpeakerId</a>
<body>
</html>

Se genera el siguiente código HTML porque no se encontró speakerid en la ruta coincidente:

<a href="/Speaker/Detail?speakerid=12">SpeakerId: 12</a>

Si no se especifica asp-controller o asp-action, se sigue el mismo proceso predeterminado que en el atributo asp-route.

asp-route

El atributo asp-route se usa para crear una dirección URL que se vincula directamente con una ruta con nombre. Mediante atributos de enrutamiento puede asignarse un nombre a una ruta tal y como se muestra en SpeakerController y usarse en su acción Evaluations:

[Route("/Speaker/Evaluations", 
       Name = "speakerevals")]

En el siguiente marcado, el atributo asp-route hace referencia a la ruta con nombre:

<a asp-route="speakerevals">Speaker Evaluations</a>

El asistente de etiquetas delimitadoras genera una ruta directamente a esa acción de controlador mediante la dirección URL /Speaker/Evaluations. El código HTML generado:

<a href="/Speaker/Evaluations">Speaker Evaluations</a>

Si además de asp-route se especifica asp-controller o asp-action, la ruta generada puede no ser la esperada. Para evitar un conflicto de ruta, no se debe usar asp-route con los atributos asp-controller y asp-action.

asp-all-route-data

El atributo asp-all-route-data permite crear un diccionario de pares clave-valor. La clave es el nombre del parámetro, mientras que el valor es el valor del parámetro.

En el ejemplo siguiente se inicializa un diccionario y se pasa a una vista de Razor. Los datos también se podrían pasar con el modelo.

@{
var parms = new Dictionary<string, string>
            {
                { "speakerId", "11" },
                { "currentYear", "true" }
            };
}

<a asp-route="speakerevalscurrent"
   asp-all-route-data="parms">Speaker Evaluations</a>

El código anterior genera el siguiente código HTML:

<a href="/Speaker/EvaluationsCurrent?speakerId=11&currentYear=true">Speaker Evaluations</a>

Se acopla el diccionario asp-all-route-data para generar una cadena de consulta que cumpla los requisitos de la acción Evaluations sobrecargada:

public IActionResult Evaluations() => View();

[Route("/Speaker/EvaluationsCurrent",
       Name = "speakerevalscurrent")]
public IActionResult Evaluations(

Si alguna de las claves del diccionario coincide con los parámetros de ruta, esos valores se sustituirán en la ruta según corresponda. Los demás valores no coincidentes se generarán como parámetros de solicitud.

asp-fragment

El atributo asp-fragment define un fragmento de dirección URL que se anexará a la dirección URL. El asistente de etiquetas delimitadoras agrega el carácter de almohadilla (#). Observe el siguiente marcado:

<a asp-controller="Speaker"
   asp-action="Evaluations"
   asp-fragment="SpeakerEvaluations">Speaker Evaluations</a>

El código HTML generado:

<a href="/Speaker/Evaluations#SpeakerEvaluations">Speaker Evaluations</a>

Las etiquetas hash son útiles al crear aplicaciones del lado cliente. Por ejemplo, se pueden usar para el marcado y la búsqueda en JavaScript.

asp-area

El atributo asp-area establece el nombre de área que se usa para establecer la ruta adecuada. En el siguiente ejemplo se muestra cómo el atributo asp-area provoca una reasignación de rutas.

Uso en Razor Pages

Se admiten áreas de Razor Pages en ASP.NET Core 2.1 o versiones posteriores.

Tenga en cuenta la siguiente jerarquía de directorios:

  • {Nombre del proyecto}
    • wwwroot
    • Áreas
      • Sesiones
        • Páginas
          • _ViewStart.cshtml
          • Index.cshtml
          • Index.cshtml.cs
    • Páginas

El marcado para hacer referencia a la página de índice de Razor del área Sesiones es:

<a asp-area="Sessions"
   asp-page="/Index">View Sessions</a>

El código HTML generado:

<a href="/Sessions">View Sessions</a>

Sugerencia

Para admitir áreas en una aplicación de Razor Pages, realice una de las siguientes acciones en Startup.ConfigureServices:

Uso en MVC

Tenga en cuenta la siguiente jerarquía de directorios:

  • {Nombre del proyecto}
    • wwwroot
    • Áreas
      • Blogs
        • Controladores
          • HomeController.cs
        • Vistas
          • Home
            • AboutBlog.cshtml
            • Index.cshtml
          • _ViewStart.cshtml
    • Controladores

Al establecer asp-area en "Blogs", el directorio Areas/Blogs se prefija en las rutas de los controladores y vistas asociados de esta etiqueta delimitadora. El marcado para hacer referencia a la vista AboutBlog es:

<a asp-area="Blogs"
   asp-controller="Home"
   asp-action="AboutBlog">About Blog</a>

El código HTML generado:

<a href="/Blogs/Home/AboutBlog">About Blog</a>

Sugerencia

Para admitir áreas en una aplicación de MVC, la plantilla de ruta debe incluir una referencia al área, en el caso de que exista. Esta plantilla se representa mediante el segundo parámetro de la llamada de método routes.MapRoute en Startup.Configure:

app.UseMvc(routes =>
{
    // need route and attribute on controller: [Area("Blogs")]
    routes.MapRoute(name: "mvcAreaRoute",
                    template: "{area:exists}/{controller=Home}/{action=Index}");

    // default route for non-areas
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

asp-protocol

El atributo asp-protocol sirve para especificar un protocolo (por ejemplo, https) en la dirección URL. Por ejemplo:

<a asp-protocol="https"
   asp-controller="Home"
   asp-action="About">About</a>

El código HTML generado:

<a href="https://localhost/Home/About">About</a>

El nombre de host en el ejemplo es localhost. El asistente de etiquetas delimitadoras utiliza el dominio público del sitio web al generar la dirección URL.

asp-host

El atributo asp-host sirve para especificar un nombre de host en la dirección URL. Por ejemplo:

<a asp-protocol="https"
   asp-host="microsoft.com"
   asp-controller="Home"
   asp-action="About">About</a>

El código HTML generado:

<a href="https://microsoft.com/Home/About">About</a>

asp-page

El atributo asp-page se usa con las Razor Page. Úselo para establecer el valor del atributo href de una etiqueta delimitadora en una página específica. Al prefijar el nombre de página con / se crea una dirección URL para una página coincidente a partir de la raíz de la aplicación:

Con el código de ejemplo, el marcado siguiente crea un vínculo a la página del asistente Razor:

<a asp-page="/Attendee">All Attendees</a>

El código HTML generado:

<a href="/Attendee">All Attendees</a>

El atributo asp-page es mutuamente excluyente con los atributos asp-route, asp-controller y asp-action. Pero se puede usar asp-page con asp-route-{value} para controlar el enrutamiento, como se muestra en el siguiente marcado:

<a asp-page="/Attendee"
   asp-route-attendeeid="10">View Attendee</a>

El código HTML generado:

<a href="/Attendee?attendeeid=10">View Attendee</a>

Si la página a la que se hace referencia no existe, se genera un vínculo a la página actual mediante un valor de ambiente de la solicitud. No se indica ninguna advertencia, excepto en el nivel de registro de depuración.

asp-page-handler

El atributo asp-page-handler se usa con las Razor Pages. Está diseñado para crear un vínculo con controladores de página específicos.

Observe el siguiente controlador de página:

public void OnGetProfile(int attendeeId)
{
    ViewData["AttendeeId"] = attendeeId;

    // code omitted for brevity
}

El marcado asociado del modelo de página se vincula con el controlador de página OnGetProfile. Tenga en cuenta que el prefijo On<Verb> del nombre de método del controlador de página se omite en el valor del atributo asp-page-handler. Cuando el método es asincrónico, también se omite el sufijo Async.

<a asp-page="/Attendee"
   asp-page-handler="Profile"
   asp-route-attendeeid="12">Attendee Profile</a>

El código HTML generado:

<a href="/Attendee?attendeeid=12&handler=Profile">Attendee Profile</a>

Recursos adicionales