Ejercicio: Uso de parámetros de ruta para mejorar la navegación de las aplicaciones

Completado

Los parámetros de ruta de Blazor permiten que los componentes accedan a los datos pasados en la dirección URL. Los parámetros de ruta permitirán que la aplicación acceda a pedidos específicos por su OrderId.

Los clientes quieren poder ver más información sobre pedidos específicos. Actualizará la página de finalización de la compra para llevar a los clientes directamente a sus pedidos realizados. A continuación, actualizará la página de pedidos para permitirles realizar un seguimiento de cualquier pedido que esté abierto actualmente.

En este ejercicio agregará una nueva página de detalles de pedido en la que se usan parámetros de ruta. Verá cómo puede agregar una restricción al parámetro para comprobar el tipo de datos correcto.

Creación de una página de detalles del pedido

  1. En el menú de Visual Studio Code, seleccione Archivo>Nuevo archivo de texto.

  2. Seleccione ASP.NET Razor como lenguaje.

  3. Cree un componente de página de detalles de pedido con este código:

    @page "/myorders/{orderId}"
    @inject NavigationManager NavigationManager
    @inject HttpClient HttpClient
    
    <div class="top-bar">
        <a class="logo" href="">
            <img src="img/logo.svg" />
        </a>
    
        <NavLink href="" class="nav-tab" Match="NavLinkMatch.All">
            <img src="img/pizza-slice.svg" />
            <div>Get Pizza</div>
        </NavLink>
    
        <NavLink href="myorders" class="nav-tab">
            <img src="img/bike.svg" />
            <div>My Orders</div>
        </NavLink>
    
    </div>
    
    <div class="main">
        @if (invalidOrder)
        {
            <h2>Order not found</h2>
            <p>We're sorry but this order no longer exists.</p>
        }
        else if (orderWithStatus == null)
        {
            <div class="track-order">
                <div class="track-order-title">
                    <h2>
                      <text>Loading...</text>
                    </h2>
                    <p class="ml-auto mb-0">
                        ...
                    </p>
                </div>
            </div>
        }
        else
        {
            <div class="track-order">
                <div class="track-order-title">
                    <h2>
                        Order placed @orderWithStatus.Order.CreatedTime.ToLongDateString()
                    </h2>
                    <p class="ml-auto mb-0">
                        Status: <strong>@orderWithStatus.StatusText</strong>
                    </p>
                </div>
                <div class="track-order-body">
                    <div class="track-order-details">
                      @foreach (var pizza in orderWithStatus.Order.Pizzas)
                      {
                          <p>
                              <strong>
                                  @(pizza.Size)"
                                  @pizza.Special.Name
                                  (£@pizza.GetFormattedTotalPrice())
                              </strong>
                          </p>
                      }
                    </div>
                </div>
            </div>
        }
    </div>
    
    @code {
        [Parameter] public int OrderId { get; set; }
    
        OrderWithStatus orderWithStatus;
        bool invalidOrder = false;
    
        protected override async Task OnParametersSetAsync()
        {
          try
          {
              orderWithStatus = await HttpClient.GetFromJsonAsync<OrderWithStatus>(
                  $"{NavigationManager.BaseUri}orders/{OrderId}");
          }
          catch (Exception ex)
          {
              invalidOrder = true;
              Console.Error.WriteLine(ex);
          }
        }
    }
    
    

    Esta página tendrá un aspecto similar al del componente MyOrders. Se realiza una llamada a OrderController, pero esta vez se solicita un pedido específico. Quiere el que coincide con OrderId. Vamos a agregar el código para procesar esta solicitud.

  4. Presione Ctrl+S para guardar los cambios.

  5. Para el nombre de archivo, use OrderDetail.razor. Asegúrese de guardar el archivo en el directorio Páginas.

  6. En el explorador de archivos, seleccione OrderController.cs.

  7. En el método PlaceOrder, agregue un nuevo método para devolver los pedidos con un estado.

    [HttpGet("{orderId}")]
    public async Task<ActionResult<OrderWithStatus>> GetOrderWithStatus(int orderId)
    {
        var order = await _db.Orders
            .Where(o => o.OrderId == orderId)
            .Include(o => o.Pizzas).ThenInclude(p => p.Special)
            .Include(o => o.Pizzas).ThenInclude(p => p.Toppings).ThenInclude(t => t.Topping)
            .SingleOrDefaultAsync();
    
        if (order == null)
        {
            return NotFound();
        }
    
        return OrderWithStatus.FromOrder(order);
    }
    

    Este código ha habilitado el controlador Pedido para responder a una solicitud HTTP con orderId en la dirección URL. A continuación, el método usa este id. para consultar la base de datos y, si se encuentra un pedido, devuelve un objeto OrderWithStatus.

    Vamos a usar esta nueva página cuando un cliente finalice la compra. Debe actualizar el componente Checkout.razor.

  8. En el explorador de archivos, expanda Páginas. Después, seleccione Checkout.razor.

  9. Cambie la llamada a lo siguiente para usar el id. del pedido realizado.

    NavigationManager.NavigateTo($"myorders/{newOrderId}");
    

    En el código existente ya se capturaba newOrderId como respuesta a la realización del pedido. Ahora puede usarlo para ir directamente a ese pedido.

Restricción del parámetro de ruta al tipo de datos correcto

La aplicación solo debe responder a las solicitudes con identificadores de orden numéricos, como (http://localhost:5000/myorders/6). No hay nada que impida que alguien intente usar pedidos no numéricos. Vamos a modificarlas.

  1. En el explorador de archivos, expanda Páginas. Después, seleccione OrderDetail.razor.

  2. Cambie el parámetro de ruta para que el componente solo acepte enteros.

    @page "/myorders/{orderId:int}"
    
  3. Ahora, si alguien intenta ir a (http://localhost:5000/myorders/non-number), el enrutamiento de Blazor no encontrará una coincidencia para la dirección URL y devolverá la página de no encontrado.

    Captura de pantalla de la página de no encontrado.

  4. En Visual Studio Code, presione F5. O bien, en el menú Ejecutar, seleccione Iniciar depuración.

    Captura de pantalla que muestra la página de detalles de un solo pedido.

    Revise la aplicación, el pedido y la finalización de la compra. Irá a la pantalla del pedido detallado y verá el estado del pedido.

  5. Pruebe distintos id. de pedido. Si usa un entero que no es un pedido válido, verá un mensaje de Pedido no encontrado.

    Captura de pantalla en la que se muestra el mensaje de pedido no encontrado.

    Si usa identificadores de pedido que no son enteros, verá que no se encuentra la página. Lo más importante es que la aplicación no tendrá una excepción no controlada.

  6. Presione Mayús + F5 para detener la aplicación.

Actualización de la página de pedidos

Por el momento, la página Mis pedidos tiene vínculos para ver más detalles, pero la dirección URL es incorrecta.

  1. En el explorador de archivos, expanda Páginas. Después, seleccione MyOrders.razor.

  2. Reemplace el elemento <a href="myorders/" class="btn btn-success"> por este código:

    <a href="myorders/@item.Order.OrderId" class="btn btn-success">
    

Puede probar que funciona si realiza el último pedido de pizza para este ejercicio. A continuación, seleccione Mis pedidos y siga el vínculo Seguimiento>.