Exercício: usar parâmetros de rota para melhorar a navegação nos aplicativos
Os parâmetros de rota do Blazor permitem que os componentes acessem os dados transmitidos na URL. Os parâmetros de rota permitem que nosso aplicativo acesse pedidos específicos por seus OrderId
.
Os clientes querem poder ver mais informações sobre pedidos específicos. Então você decide atualizar a página de check-out a fim de levar os clientes diretamente para seus pedidos feitos. Em seguida, você precisa atualizar a página de pedidos para permitir que eles acompanhem todos os pedidos abertos no momento.
Neste exercício, você adiciona uma nova página de detalhes do pedido que usa parâmetros de rota. Então você visualiza como adicionar uma restrição ao parâmetro para conferir o tipo de dados correto.
Criar uma página de detalhes do pedido
No menu do Visual Studio Code, escolha Arquivo>Novo arquivo de texto.
Selecione ASP.NET Razor como a linguagem.
Crie um componente de página de detalhes do pedido com 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 é semelhante ao componente MyOrders. Estamos fazendo uma chamada a OrderController, mas desta vez estamos fazendo um pedido específico. Queremos aquele que corresponde a
OrderId
. Vamos adicionar o código que processa essa solicitação.Salve suas alterações selecionando Ctrl+S.
Como o nome do arquivo, use OrderDetail.razor. Salve o arquivo no diretório Páginas.
No explorador de arquivos, selecione OrderController.cs.
No método
PlaceOrder
, adicione um novo método para retornar pedidos com um status.[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); }
Esse código permitiu que o controlador Order respondesse a uma solicitação HTTP com a orderId na URL. Em seguida, o método usa esse ID para consultar o banco de dados e, se um pedido for encontrado, retornar um objeto
OrderWithStatus
.Vamos usar essa nova página quando um cliente faz check-out. Você precisa atualizar o componente Checkout.razor.
No explorador de arquivos, expanda Páginas. Em seguida, selecione Checkout.razor.
Altere a chamada para a seguinte a fim de usar a ID do pedido feito.
NavigationManager.NavigateTo($"myorders/{newOrderId}");
O código existente já estava capturando a
newOrderId
como a resposta ao pedido feito. Agora você pode usá-la para acessar diretamente esse pedido.
Restringir o parâmetro de rota ao tipo de dados correto
O aplicativo só deve responder a solicitações com IDs de pedido numéricas, como (http://localhost:5000/myorders/6)
. Não há nada que impeça alguém de tentar usar pedidos não numéricos. Vamos mudar isso.
No explorador de arquivos, expanda Páginas. Em seguida, selecione OrderDetail.razor.
Altere o parâmetro de rota para que o componente aceite apenas inteiros.
@page "/myorders/{orderId:int}"
Agora, se alguém tentar acessar
(http://localhost:5000/myorders/non-number)
, o roteamento do Blazor não encontrará uma correspondência para o URL e retornará o aviso de página não encontrada.No Visual Studio Code, selecione F5. Ou, então, no menu Executar, selecione Iniciar Depuração.
Acesse o aplicativo, faça o pedido e finalize a compra. Você é levado para a tela de pedido detalhada e visualize o status do pedido.
Experimente IDs de pedidos diferentes. Se você usar um inteiro que não é um pedido válido, receberá a mensagem Pedido não encontrado.
Se você usar IDs de pedido não inteiras, visualizará a página Pedido não encontrado. E o mais importante: o aplicativo não tem uma exceção sem tratamento.
Para parar o aplicativo, selecione Shift + F5.
Atualizar a página de pedidos
No momento, a página Meus Pedidos tem links para exibir mais detalhes, mas a URL está errada.
No explorador de arquivos, expanda Páginas. Em seguida, selecione MyOrders.razor.
Substitua o elemento
<a href="myorders/" class="btn btn-success">
por este código:<a href="myorders/@item.Order.OrderId" class="btn btn-success">
Teste esse código funciona fazendo seu último pedido de pizza neste exercício. Selecione Meus Pedidos e siga o link Acompanhar >.