Compartir a través de


Páginas, enrutamiento y diseños

Sugerencia

Este contenido es un extracto del libro electrónico "Blazor for ASP.NET Web Forms Developers for Azure" (Blazor para desarrolladores de ASP.NET Web Forms), disponible en Documentación de .NET o como un PDF descargable y gratuito que se puede leer sin conexión.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover thumbnail.

Las aplicaciones de ASP.NET Web Forms se componen de páginas definidas en archivos .aspx. La dirección de cada página se basa en su ruta de archivo física en el proyecto. Cuando un explorador realiza una solicitud a la página, el contenido de la página se representa de forma dinámica en el servidor. La representación tiene en cuenta tanto el marcado HTML de la página como sus controles de servidor.

En Blazor, cada página de la aplicación es un componente, que normalmente se define en un archivo .razor, con una o varias rutas especificadas. El enrutamiento se produce principalmente en el lado cliente sin implicar una solicitud de servidor concreta. En primer lugar, el explorador realiza una solicitud a la dirección raíz de la aplicación. Después, un componente Router raíz de la aplicación Blazor controla la interceptación de las solicitudes de navegación y las reenvía al componente correcto.

Blazor también admite la vinculación en profundidad. La vinculación en profundidad se produce cuando el explorador realiza una solicitud a una ruta concreta distinta de la raíz de la aplicación. Las solicitudes de vínculos profundos enviadas al servidor se enrutan a la aplicación Blazor, que, después, enruta el lado cliente de la solicitud al componente correcto.

Una página simple de ASP.NET Web Forms podría contener el marcado siguiente:

Name.aspx

<%@ Page Title="Name" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Name.aspx.cs" Inherits="WebApplication1.Name" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <div>
        What is your name?<br />
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
    </div>
    <div>
        <asp:Literal ID="Literal1" runat="server" />
    </div>
</asp:Content>

Name.aspx.cs

public partial class Name : System.Web.UI.Page
{
    protected void Button1_Click1(object sender, EventArgs e)
    {
        Literal1.Text = "Hello " + TextBox1.Text;
    }
}

La página equivalente en una aplicación Blazor tendría este aspecto:

Name.razor

@page "/Name"
@layout MainLayout

<div>
    What is your name?<br />
    <input @bind="text" />
    <button @onclick="OnClick">Submit</button>
</div>
<div>
    @if (name != null)
    {
        @:Hello @name
    }
</div>

@code {
    string text;
    string name;

    void OnClick() {
        name = text;
    }
}

Creación de páginas

Para crear una página en Blazor, cree un componente y agregue la directiva @page de Razor para especificar la ruta del componente. La directiva @page toma un único parámetro, que es la plantilla de ruta que se va a agregar a ese componente.

@page "/counter"

El parámetro de la plantilla de ruta es obligatorio. A diferencia de ASP.NET Web Forms, la ruta a un componente de Blazorno se infiere de su ubicación de archivo (aunque puede ser una característica que se agregue en el futuro).

La sintaxis de la plantilla de ruta es la misma sintaxis básica que se usa para el enrutamiento en ASP.NET Web Forms. Los parámetros de ruta se especifican en la plantilla mediante llaves. Blazor enlazará los valores de ruta a los parámetros de componente con el mismo nombre (sin distinción de mayúsculas y minúsculas).

@page "/product/{id}"

<h1>Product @Id</h1>

@code {
    [Parameter]
    public string Id { get; set; }
}

También puede especificar restricciones en el valor del parámetro de ruta. Por ejemplo, para restringir el identificador de producto a int:

@page "/product/{id:int}"

<h1>Product @Id</h1>

@code {
    [Parameter]
    public int Id { get; set; }
}

Para obtener una lista completa de las restricciones de ruta admitidas por Blazor, vea Restricciones de ruta.

Componente de enrutador

En Blazor, el componente Router controla el enrutamiento. El componente Router se usa normalmente en el componente raíz de la aplicación (App.razor).

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

El componente Router detecta los componentes enrutables en el elemento AppAssembly especificado y opcionalmente en AdditionalAssemblies. Cuando el explorador navega, Router intercepta la navegación y representa el contenido de su parámetro Found con el objeto RouteData extraído si una ruta coincide con la dirección; de lo contrario, Router representa su parámetro NotFound.

El componente RouteView controla la representación del componente coincidente especificado por RouteData con su diseño, si lo tiene. Si el componente coincidente no tiene un diseño, se usa el objeto DefaultLayout especificado de manera opcional.

El componente LayoutView representa su contenido secundario dentro del diseño especificado. Los diseños se describirán con más detalle más adelante en este capítulo.

En ASP.NET Web Forms, para desencadenar la navegación a una página diferente se devuelve una respuesta de redirección al explorador. Por ejemplo:

protected void NavigateButton_Click(object sender, EventArgs e)
{
    Response.Redirect("Counter");
}

Normalmente no es posible devolver una respuesta de redireccionamiento en Blazor. En Blazor no se usa un modelo de solicitud-respuesta. Pero puede desencadenar directamente las navegaciones del explorador, como se puede hacer con JavaScript.

Blazor proporciona un servicio NavigationManager que se puede usar para lo siguiente:

  • Obtener la dirección actual del explorador
  • Obtener la dirección base
  • Desencadenar navegaciones
  • Recibir una notificación cuando cambie la dirección

Para navegar a otra dirección, use el método NavigateTo:

@page "/"
@inject NavigationManager NavigationManager

<button @onclick="Navigate">Navigate</button>

@code {
    void Navigate() {
        NavigationManager.NavigateTo("counter");
    }
}

Para obtener una descripción de todos los miembros de NavigationManager, vea Aplicaciones auxiliares de URI y estado de navegación.

Direcciones URL base

Si la aplicación Blazor se implementa en una ruta de acceso base, debe especificar la dirección URL base en los metadatos de la página mediante la etiqueta <base> para el enrutamiento de la propiedad de trabajo. Si la página de host de la aplicación se representa en el servidor mediante Razor, puede usar la sintaxis ~/ para especificar la dirección base de la aplicación. Si la página de host es código HTML estático, debe especificar de forma explícita la dirección URL base.

<base href="~/" />

Diseño de página

El diseño de página en ASP.NET Web Forms se controla mediante páginas maestras. Las páginas maestras definen una plantilla con uno o varios marcadores de posición de contenido que las páginas individuales pueden proporcionar. Las páginas maestras se definen en archivos .master y comienzan con la directiva <%@ Master %>. El contenido de los archivos .master se codifica como una página .aspx, pero se agregan controles <asp:ContentPlaceHolder> para marcar dónde pueden proporcionar contenido las páginas.

Site.master

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication1.SiteMaster" %>

<!DOCTYPE html>
<html lang="en">
<head runat="server">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><%: Page.Title %> - My ASP.NET Application</title>
    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
    <form runat="server">
        <div class="container body-content">
            <asp:ContentPlaceHolder ID="MainContent" runat="server">
            </asp:ContentPlaceHolder>
            <hr />
            <footer>
                <p>&copy; <%: DateTime.Now.Year %> - My ASP.NET Application</p>
            </footer>
        </div>
    </form>
</body>
</html>

En Blazor, el diseño de página se controla mediante componentes de diseño. Los componentes de diseño heredan de LayoutComponentBase, que define una sola propiedad Body de tipo RenderFragment, que se puede usar para representar el contenido de la página.

MainLayout.razor

@inherits LayoutComponentBase
<h1>Main layout</h1>
<div>
    @Body
</div>

Cuando la página se representa con un diseño, la página se representa en el contenido del diseño especificado en la ubicación en la que el diseño representa su propiedad Body.

Para aplicar un diseño a una página, use la directiva @layout:

@layout MainLayout

Puede especificar el diseño de todos los componentes en una carpeta y subcarpetas mediante un archivo _Imports.razor. También puede especificar un diseño predeterminado para todas las páginas mediante el componente de enrutador.

Las páginas maestras pueden definir varios marcadores de posición de contenido, pero los diseños de Blazor solo tienen una propiedad Body. Esperamos que esta limitación de los componentes de diseño de Blazor se solucione en una versión futura.

Las páginas maestras en ASP.NET Web Forms se pueden anidar. Es decir, una página maestra también puede usar una página maestra. Los componentes de diseño de Blazor también se pueden anidar. Puede aplicar un componente de diseño a un componente de diseño. El contenido del diseño interno se representará dentro del diseño externo.

ChildLayout.razor

@layout MainLayout
<h2>Child layout</h2>
<div>
    @Body
</div>

Index.razor

@page "/"
@layout ChildLayout
<p>I'm in a nested layout!</p>

La salida representada de la página sería la siguiente:

<h1>Main layout</h1>
<div>
    <h2>Child layout</h2>
    <div>
        <p>I'm in a nested layout!</p>
    </div>
</div>

En Blazor, normalmente los diseños no definen los elementos HTML raíz de una página (<html>, <body>, <head>, etc.). En su lugar, los elementos HTML raíz se definen en la página de host de una aplicación Blazor, que se usa para representar el contenido HTML inicial de la aplicación (Vea Arranque de Blazor). La página de host puede representar varios componentes raíz para la aplicación con el marcado circundante.

Los componentes de Blazor, incluidas las páginas, no pueden representar etiquetas <script>. Esta restricción de representación existe porque las etiquetas <script> se cargan una vez y, después, no se pueden cambiar. Si intenta representar las etiquetas de forma dinámica con la sintaxis de Razor, se puede producir un comportamiento inesperado. En su lugar, todas las etiquetas <script> se deben agregar a la página de host de la aplicación.