Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to .NET 6 #330

Merged
merged 21 commits into from
Mar 28, 2022
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>
csharpfritz marked this conversation as resolved.
Show resolved Hide resolved
<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>
csharpfritz marked this conversation as resolved.
Show resolved Hide resolved
</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>
csharpfritz marked this conversation as resolved.
Show resolved Hide resolved
</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);
csharpfritz marked this conversation as resolved.
Show resolved Hide resolved

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);
csharpfritz marked this conversation as resolved.
Show resolved Hide resolved
}
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