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 all 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
  •  
  •  
  •  
189 changes: 189 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Rules in this file were initially inferred by Visual Studio IntelliCode from the C:\dev\dnp\blazor-workshop\src codebase based on best match to current usage at 3/28/2022
# You can modify the rules from these initially generated values to suit your own policies
# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
[*.cs]


#Formatting - new line options

#place catch statements on a new line
csharp_new_line_before_catch = true
#place else statements on a new line
csharp_new_line_before_else = true
#require members of anonymous types to be on separate lines
csharp_new_line_before_members_in_anonymous_types = true
#require members of object intializers to be on separate lines
csharp_new_line_before_members_in_object_initializers = true
#require braces to be on a new line for methods, control_blocks, types, object_collection_array_initializers, and anonymous_types (also known as "Allman" style)
csharp_new_line_before_open_brace = methods, control_blocks, types, object_collection_array_initializers, anonymous_types

#Formatting - organize using options

#sort System.* using directives alphabetically, and place them before other usings
dotnet_sort_system_directives_first = true

#Formatting - spacing options

#require NO space between a cast and the value
csharp_space_after_cast = false
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_after_colon_in_inheritance_clause = true
#require a space after a keyword in a control flow statement such as a for loop
csharp_space_after_keywords_in_control_flow_statements = true
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_before_colon_in_inheritance_clause = true
#remove space within empty argument list parentheses
csharp_space_between_method_call_empty_parameter_list_parentheses = false
#remove space between method call name and opening parenthesis
csharp_space_between_method_call_name_and_opening_parenthesis = false
#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call
csharp_space_between_method_call_parameter_list_parentheses = false
#remove space within empty parameter list parentheses for a method declaration
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list.
csharp_space_between_method_declaration_parameter_list_parentheses = false

#Formatting - wrapping options

#leave code block on single line
csharp_preserve_single_line_blocks = true

#Style - Code block preferences

#prefer curly braces even for one line of code
csharp_prefer_braces = true:suggestion

#Style - expression bodied member options

#prefer block bodies for constructors
csharp_style_expression_bodied_constructors = false:suggestion
#prefer block bodies for methods
csharp_style_expression_bodied_methods = false:suggestion
#prefer expression-bodied members for properties
csharp_style_expression_bodied_properties = true:suggestion

#Style - expression level options

#prefer ItemX properties to tuple names
dotnet_style_explicit_tuple_names = false:suggestion
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_member_access = true:suggestion

#Style - Expression-level preferences

#prefer objects to be initialized using object initializers when possible
dotnet_style_object_initializer = true:suggestion
#prefer inferred anonymous type member names
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
#prefer inferred tuple element names
dotnet_style_prefer_inferred_tuple_names = true:suggestion

#Style - implicit and explicit types

#prefer var over explicit type in all cases, unless overridden by another code style rule
csharp_style_var_elsewhere = true:suggestion
#prefer var is used to declare variables with built-in system types such as int
csharp_style_var_for_built_in_types = true:suggestion
#prefer var when the type is already mentioned on the right-hand side of a declaration expression
csharp_style_var_when_type_is_apparent = true:suggestion

#Style - language keyword and framework type options

#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion

#Style - modifier options

#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods.
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion

#Style - Modifier preferences

#when this rule is set to a list of modifiers, prefer the specified ordering.
csharp_preferred_modifier_order = public,private,protected,static,async,readonly,override:suggestion

#Style - qualification options

#prefer fields not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_field = false:suggestion
#prefer methods not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_indent_labels = one_less_than_current

[*.{cs,vb}]
#### Naming styles ####

# Naming rules

dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i

dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case

dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case

# Symbol specifications

dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =

dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =

dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =

# Naming styles

dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case

dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = false:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
indent_style = space
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_prefer_simplified_interpolation = true:suggestion
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);
}
Loading