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 permiten a nuestra aplicación acceder a pedidos específicos por su OrderId.

Los clientes quieren poder ver más información sobre pedidos específicos. Por lo tanto, decide actualizar la página de desprotección para llevar a los clientes directamente a sus pedidos realizados. A continuación, quiere actualizar la página de pedidos para permitirles realizar un seguimiento de cualquier pedido abierto actualmente.

En este ejercicio, agregará una nueva página de detalles de pedido que usa parámetros de ruta. A continuación, 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 tiene un aspecto similar al 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 que procesa esta solicitud.

  4. Para guardar los cambios, seleccione Ctrl+S.

  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 route 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 encuentra una coincidencia para la dirección URL y devuelve la página no encontrada.

    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.

    Recorra la aplicación, ordene y consulte. Se le lleva a la pantalla de pedidos detallado y ve el estado del pedido.

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

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

    Si usa identificadores de pedido no enteros, verá que no se encuentra la página. Más importante, la aplicación no tiene una excepción no controlada.

  6. Para detener la aplicación, seleccione Mayús + F5.

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">
    

Para probar cómo funciona este código, realice el último pedido de pizza para este ejercicio. A continuación, seleccione Mis pedidos y siga el vínculo Seguimiento>.