Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 5 additions & 4 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<Project>
<PropertyGroup>
<AspNetCoreVersion>5.0.0</AspNetCoreVersion>
<BlazorVersion>5.0.0</BlazorVersion>
<EntityFrameworkVersion>5.0.0</EntityFrameworkVersion>
<SystemNetHttpJsonVersion>5.0.0</SystemNetHttpJsonVersion>
<AspNetCoreVersion>6.0.0</AspNetCoreVersion>
<BlazorVersion>6.0.0</BlazorVersion>
<EntityFrameworkVersion>6.0.0</EntityFrameworkVersion>
<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>
<SystemNetHttpJsonVersion>6.0.0</SystemNetHttpJsonVersion>
</PropertyGroup>
</Project>
20 changes: 20 additions & 0 deletions docs/03-show-order-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ Now when you run the app, you'll be able to visit this page:

Also notice that this time, no full-page load occurs when you navigate, because the URL is matched entirely within the client-side SPA. As such, navigation is instantaneous.

## Adding a page title

In your browser, the title of the new page is listed as **Blazing Pizza** and it would be nice to update the title to reflect that this is the 'My Orders' page. We can use the new `PageTitle` component to update the title from the `MyOrders.razor` page:

```html
@page "/myorders"

<PageTitle>Blazing Pizza - My Orders</PageTitle>

<div class="main">
My orders will go here
</div>
```

This works because inside the `Program.cs` file is an entry that adds a `HeadOutlet` component to the HTML presenting the BlazingPizza application. Blazor uses this `HeadOutlet` to write content into the header of the HTML page.

```csharp
builder.RootComponents.Add<HeadOutlet>("head::after");
```

## Highlighting navigation position

Look closely at the top bar. Notice that when you're on "My orders", the link *isn't* highlighted in yellow. How can we highlight links when the user is on them? By using a `NavLink` component instead of a plain `<a>` tag. The only special thing a `NavLink` component does is toggle its own `active` CSS class depending on whether its `href` matches the current navigation state.
Expand Down
2 changes: 2 additions & 0 deletions docs/05-checkout-with-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ It's time to fix this by adding a "checkout" screen that requires customers to e
Start by adding a new page component, `Checkout.razor`, with a `@page` directive matching the URL `/checkout`. For the initial markup, let's display the details of the order using your `OrderReview` component:

```razor
<PageTitle>Blazing Pizza - Checkout</PageTitle>

<div class="main">
<div class="checkout-cols">
<div class="checkout-order-details">
Expand Down
42 changes: 42 additions & 0 deletions docs/06-authentication-and-authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,48 @@ builder.Services.AddHttpClient<OrdersClient>(client => client.BaseAddress = new
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
```

### Optional: Optimize JSON interactions with .NET 6 JSON CodeGeneration

Starting with .NET 6, the System.Text.Json.JsonSerializer supports working with optimized code generated for serializing and deserializing JSON payloads. Code is generated at build time, resulting in a significant performance improvement for the serialization and deserialization of JSON data. This is configured by taking the following steps:

1. Create a partial Context class that inherits from `System.Text.Json.Serialization.JsonSerializerContext`
2. Decorate the class with the `System.Text.Json.JsonSourceGenerationOptions` attribute
3. Add `JsonSerializable` attributes to the class definition for each type that you would like to have code generated

We have already written this context for you and it is located in the `BlazingPizza.Shared.Order.cs" file

```csharp
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Default, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(Order))]
[JsonSerializable(typeof(OrderWithStatus))]
[JsonSerializable(typeof(List<OrderWithStatus>))]
[JsonSerializable(typeof(Pizza))]
[JsonSerializable(typeof(List<PizzaSpecial>))]
[JsonSerializable(typeof(List<Topping>))]
[JsonSerializable(typeof(Topping))]
public partial class OrderContext : JsonSerializerContext {}
```

You can now optimize the calls to the HttpClient in the `OrdersClient` class by passing an `OrderContext.Default` parameter pointing to the type sought as the second parameter. Updating the methods in the `OrdersClient` class should look like the following:

```csharp
public async Task<IEnumerable<OrderWithStatus>> GetOrders() =>
await httpClient.GetFromJsonAsync("orders", OrderContext.Default.ListOrderWithStatus);

public async Task<OrderWithStatus> GetOrder(int orderId) =>
await httpClient.GetFromJsonAsync($"orders/{orderId}", OrderContext.Default.OrderWithStatus);

public async Task<int> PlaceOrder(Order order)
{
var response = await httpClient.PostAsJsonAsync("orders", order, OrderContext.Default.Order);
response.EnsureSuccessStatusCode();
var orderId = await response.Content.ReadFromJsonAsync<int>();
return orderId;
}
```

### Deploy OrdersClient to pages

Update each page where an `HttpClient` is used to manage orders to use the new typed `OrdersClient`. Inject an `OrdersClient` instead of an `HttpClient` and use the new client to make the API call. Wrap each call in a `try-catch` that handles exceptions of type `AccessTokenNotAvailableException` by calling the provided `Redirect()` method.

*Checkout.razor*
Expand Down
16 changes: 8 additions & 8 deletions src/nuget.config → nuget.config
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>$(TargetFrameworkVersion)</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
26 changes: 8 additions & 18 deletions save-points/00-get-started/BlazingPizza.Client/Program.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using BlazingPizza.Client;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

namespace BlazingPizza.Client
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();
}
}
}
await builder.Build().RunAsync();
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>$(TargetFrameworkVersion)</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
using Microsoft.JSInterop;
using System.Threading.Tasks;

namespace BlazingPizza.ComponentsLibrary
namespace BlazingPizza.ComponentsLibrary;

public static class LocalStorage
{
public static class LocalStorage
{
public static ValueTask<T> GetAsync<T>(IJSRuntime jsRuntime, string key)
=> jsRuntime.InvokeAsync<T>("blazorLocalStorage.get", key);
public static ValueTask<T> GetAsync<T>(IJSRuntime jsRuntime, string key)
=> jsRuntime.InvokeAsync<T>("blazorLocalStorage.get", key);

public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value)
=> jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value);
public static ValueTask SetAsync(IJSRuntime jsRuntime, string key, object value)
=> jsRuntime.InvokeVoidAsync("blazorLocalStorage.set", key, value);

public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key)
=> jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key);
}
public static ValueTask DeleteAsync(IJSRuntime jsRuntime, string key)
=> jsRuntime.InvokeVoidAsync("blazorLocalStorage.delete", key);
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
namespace BlazingPizza.ComponentsLibrary.Map
namespace BlazingPizza.ComponentsLibrary.Map;

public class Marker
{
public class Marker
{
public string Description { get; set; }
public string Description { get; set; }

public double X { get; set; }
public double X { get; set; }

public double Y { get; set; }
public double Y { get; set; }

public bool ShowPopup { get; set; }
}
}
public bool ShowPopup { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
namespace BlazingPizza.ComponentsLibrary.Map
namespace BlazingPizza.ComponentsLibrary.Map;

public class Point
{
public class Point
{
public double X { get; set; }
public double X { get; set; }

public double Y { get; set; }
}
}
public double Y { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>$(TargetFrameworkVersion)</TargetFramework>
<ImplicitUsings>true</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace BlazingPizza.Server
namespace BlazingPizza.Server;

public class OidcConfigurationController : Controller
{
public class OidcConfigurationController : Controller
{
public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider)
{
ClientRequestParametersProvider = clientRequestParametersProvider;
}
public OidcConfigurationController(IClientRequestParametersProvider clientRequestParametersProvider)
{
ClientRequestParametersProvider = clientRequestParametersProvider;
}

public IClientRequestParametersProvider ClientRequestParametersProvider { get; }
public IClientRequestParametersProvider ClientRequestParametersProvider { get; }

[HttpGet("_configuration/{clientId}")]
public IActionResult GetClientRequestParameters([FromRoute]string clientId)
{
var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId);
return Ok(parameters);
}
}
}
[HttpGet("_configuration/{clientId}")]
public IActionResult GetClientRequestParameters([FromRoute] string clientId)
{
var parameters = ClientRequestParametersProvider.GetClientParameters(HttpContext, clientId);
return Ok(parameters);
}
}
Loading