Esercizio: Usare i parametri di route per migliorare lo spostamento delle app
I parametri di route di Blazor consentono ai componenti di accedere ai dati passati nell'URL. Con i parametri di route l'app può accedere a ordini specifici in base al valore di OrderId
.
I clienti vogliono poter visualizzare altre informazioni su ordini specifici. Verrà quindi aggiornata la pagina di completamento della transazione in modo da visualizzare direttamente ai clienti gli ordini inseriti. Si aggiornerà quindi la pagina degli ordini per consentire loro di tenere traccia di qualsiasi ordine attualmente aperto.
In questo esercizio si aggiungerà una nuova pagina dei dettagli dell'ordine in cui vengono usati parametri di route. Verrà illustrato come aggiungere un vincolo al parametro per controllare il tipo di dati corretto.
Creare una pagina dei dettagli dell'ordine
In Visual Studio Code scegliere File>Nuovo file di testo dal menu.
Selezionare ASP.NET Razor come linguaggio.
Creare un componente della pagina dei dettagli dell'ordine con questo codice:
@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); } } }
Questa pagina sarà simile al componente MyOrders. Verrà effettuata una chiamata a OrderController, ma questa volta per richiedere un ordine specifico. Si vuole ottenere l'ordine corrispondente al valore di
OrderId
. Verrà quindi aggiunto il codice per elaborare questa richiesta.Premere CTRL+S per salvare le modifiche.
Come nome file usare OrderDetail.razor. Assicurarsi di salvare il file nella directory Pages.
In Esplora file selezionare OrderController.cs.
Nel metodo
PlaceOrder
aggiungere un nuovo metodo per restituire gli ordini con uno stato.[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); }
Questo codice ha abilitato il controller Order per rispondere a una richiesta HTTP il cui URL include orderId. Il metodo usa quindi questo ID per eseguire una query sul database e, se viene trovato un ordine, restituire un oggetto
OrderWithStatus
.Questa nuova pagina verrà usata quando il cliente completa la transazione. È necessario aggiornare il componente Checkout.razor.
In Esplora file espandere Pages. Selezionare quindi Checkout.razor.
Modificare la chiamata alla seguente per usare l'ID ordine dell'ordine inserito.
NavigationManager.NavigateTo($"myorders/{newOrderId}");
Il codice esistente acquisiva già
newOrderId
come risposta dall'inserimento dell'ordine. È ora possibile usarlo per passare direttamente a tale ordine.
Limitare il parametro di route al tipo di dati corretto
L'app deve rispondere solo alle richieste con ID ordine numerico, ad esempio (http://localhost:5000/myorders/6)
. Non c'è nulla che impedisca a un utente di provare a usare ordini non numerici. Si può cambiare.
In Esplora file espandere Pages. Selezionare quindi OrderDetail.razor.
Modificare il parametro di route in modo che il componente accetti solo numeri interi.
@page "/myorders/{orderId:int}"
Ora se un utente prova ad accedere a
(http://localhost:5000/myorders/non-number)
, il routing Blazor non troverà una corrispondenza per l'URL e restituirà il messaggio di pagina non trovata.In Visual Studio Code selezionare F5. In alternativa, selezionare Avvia debug nel menu Esegui.
Esaminare app, ordine e completamento della transazione. Verrà visualizzata la schermata dell'ordine dettagliato in cui è indicato lo stato dell'ordine.
Provare con ID ordine diversi. Se si usa un numero intero che non corrisponde a un ID ordine valido, verrà visualizzato un messaggio Order not found (Ordine non trovato).
Se si usano ID ordine non costituiti da numeri interi, verrà visualizzato il messaggio di pagina non trovata. Più importante, nell'app non si verificherà un'eccezione non gestita.
Selezionare MAIUSC + F5 per arrestare l'app.
Aggiornare la pagina degli ordini
Al momento, la pagina My Orders (Ordini personali) contiene collegamenti per visualizzare maggiori dettagli, ma l'URL non è corretto.
In Esplora file espandere Pages. Selezionare quindi MyOrders.razor.
Sostituire l'elemento
<a href="myorders/" class="btn btn-success">
con il codice seguente:<a href="myorders/@item.Order.OrderId" class="btn btn-success">
È ora possibile testarne il funzionamento effettuando l'ultimo ordine di pizze per questo esercizio. Selezionare quindi My Orders (Ordini personali) e seguire il collegamento Track > (Tieni traccia).