Skip to content

Commit f194417

Browse files
Merge pull request #33883 from dotnet/main
Merge to Live
2 parents 6c0cbc6 + 5a02d01 commit f194417

File tree

27 files changed

+85
-113
lines changed

27 files changed

+85
-113
lines changed

aspnetcore/blazor/blazor-ef-core.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ The grid, add, and view components use the "context-per-operation" pattern, wher
103103
> [!NOTE]
104104
> Some of the code examples in this topic require namespaces and services that aren't shown. To inspect the fully working code, including the required [`@using`](xref:mvc/views/razor#using) and [`@inject`](xref:mvc/views/razor#inject) directives for Razor examples, see the [sample app](#sample-app).
105105
106+
:::moniker range=">= aspnetcore-8.0"
107+
108+
## Build a Blazor movie database app tutorial
109+
110+
For a tutorial experience building an app that uses EF Core to work with a database, see <xref:blazor/tutorials/movie-database-app/index>. The tutorial shows you how to create a Blazor Web App that can display and manage movies in a movie database.
111+
112+
:::moniker-end
113+
106114
## Database access
107115

108116
EF Core relies on a <xref:Microsoft.EntityFrameworkCore.DbContext> as the means to [configure database access](/ef/core/miscellaneous/configuring-dbcontext) and act as a [*unit of work*](https://martinfowler.com/eaaCatalog/unitOfWork.html). EF Core provides the <xref:Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.AddDbContext%2A> extension for ASP.NET Core apps that registers the context as a *scoped* service. In server-side Blazor apps, scoped service registrations can be problematic because the instance is shared across components within the user's circuit. <xref:Microsoft.EntityFrameworkCore.DbContext> isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate for these reasons:

aspnetcore/blazor/debug.md

Lines changed: 9 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ Blazor Server: [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://ww
164164

165165
:::moniker-end
166166

167-
Standalone Blazor WebAssembly: [`Microsoft.AspNetCore.Components.WebAssembly.DevServer`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.DevServer): Development server for use when building Blazor apps. Calls <xref:Microsoft.AspNetCore.Builder.WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging%2A?displayProperty=nameWithType> internally to add middleware for debugging Blazor WebAssembly apps inside Chromium developer tools.
167+
Standalone Blazor WebAssembly: [`Microsoft.AspNetCore.Components.WebAssembly.DevServer`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.DevServer): Development server for use when building Blazor apps. Calls <xref:Microsoft.AspNetCore.Builder.WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging%2A> internally to add middleware for debugging Blazor WebAssembly apps inside Chromium developer tools.
168168

169169
:::moniker range="< aspnetcore-8.0"
170170

171171
Hosted Blazor WebAssembly:
172172

173-
* **:::no-loc text="Client":::** project: [`Microsoft.AspNetCore.Components.WebAssembly.DevServer`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.DevServer): Development server for use when building Blazor apps. Calls <xref:Microsoft.AspNetCore.Builder.WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging%2A?displayProperty=nameWithType> internally to add middleware for debugging Blazor WebAssembly apps inside Chromium developer tools.
173+
* **:::no-loc text="Client":::** project: [`Microsoft.AspNetCore.Components.WebAssembly.DevServer`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.DevServer): Development server for use when building Blazor apps. Calls <xref:Microsoft.AspNetCore.Builder.WebAssemblyNetDebugProxyAppBuilderExtensions.UseWebAssemblyDebugging%2A> internally to add middleware for debugging Blazor WebAssembly apps inside Chromium developer tools.
174174
* **:::no-loc text="Server":::** project: [`Microsoft.AspNetCore.Components.WebAssembly.Server`](https://www.nuget.org/packages/Microsoft.AspNetCore.Components.WebAssembly.Server): References an internal package ([`Microsoft.NETCore.BrowserDebugHost.Transport`](https://github.com/dotnet/runtime/blob/main/src/mono/nuget/Microsoft.NETCore.BrowserDebugHost.Transport/Microsoft.NETCore.BrowserDebugHost.Transport.pkgproj)) for assemblies that share the browser debug host.
175175

176176
:::moniker-end
@@ -187,43 +187,17 @@ The example in this section assumes that you've created a Blazor Web App with an
187187

188188
1. Open the app.
189189
1. Set a breakpoint on the `currentCount++;` line in the `Counter` component (`Pages/Counter.razor`) of the client project (`.Client`).
190-
1. Press <kbd>F5</kbd> to run the app in the debugger.
190+
1. With the server project selected in **Solution Explorer**, press <kbd>F5</kbd> to run the app in the debugger.
191191
1. In the browser, navigate to `Counter` page at `/counter`. Wait a few seconds for the debug proxy to load and run. Select the **Click me** button to hit the breakpoint.
192192
1. In Visual Studio, inspect the value of the `currentCount` field in the **Locals** window.
193193
1. Press <kbd>F5</kbd> to continue execution.
194194

195195
Breakpoints can also be hit in the server project in statically-rendered and interactively-rendered server-side components.
196196

197197
1. Stop the debugger.
198-
1. Add the following component to the server app. The component applies the Interactive Server render mode (`InteractiveServer`).
199-
200-
`Components/Pages/Counter2.razor`:
201-
202-
```razor
203-
@page "/counter-2"
204-
@rendermode InteractiveServer
205-
206-
<PageTitle>Counter 2</PageTitle>
207-
208-
<h1>Counter 2</h1>
209-
210-
<p role="status">Current count: @currentCount</p>
211-
212-
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
213-
214-
@code {
215-
private int currentCount = 0;
216-
217-
private void IncrementCount()
218-
{
219-
currentCount++;
220-
}
221-
}
222-
```
223-
224-
1. Set a breakpoint on the `currentCount++;` line in the `Counter2` component.
198+
1. In the server app, open the statically-rendered `Weather` component (`Components/Pages/Weather.razor`) and set a breakpoint anywhere in the `OnInitializedAsync` method.
225199
1. Press <kbd>F5</kbd> to run the app in the debugger.
226-
1. In the browser, navigate to `Counter2` page at `/counter-2`. Wait a few seconds for the debug proxy to load and run. Select the **Click me** button to hit the breakpoint.
200+
1. In the browser, navigate to the `Weather` page at `/weather`. Wait a few seconds for the debug proxy to load and run. Application execution stops at the breakpoint.
227201
1. Press <kbd>F5</kbd> to continue execution.
228202

229203
Breakpoints are **not** hit during app startup before the debug proxy is running. This includes breakpoints in the `Program` file and breakpoints in the [`OnInitialized{Async}` lifecycle methods](xref:blazor/components/lifecycle#component-initialization-oninitializedasync) of components that are loaded by the first page requested from the app.
@@ -241,35 +215,9 @@ The example in this section assumes that you've created a Blazor Web App with an
241215
Breakpoints can also be hit in the server project.
242216

243217
1. Stop debugging by selecting the **Stop** button or press <kbd>Shift</kbd>+<kbd>F5</kbd> on the keyboard.
244-
1. Add the following component to the server app. The component adopts the Interactive Server render mode (`InteractiveServer`).
245-
246-
`Components/Pages/Counter2.razor`:
247-
248-
```razor
249-
@page "/counter-2"
250-
@rendermode InteractiveServer
251-
252-
<PageTitle>Counter 2</PageTitle>
253-
254-
<h1>Counter 2</h1>
255-
256-
<p role="status">Current count: @currentCount</p>
257-
258-
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
259-
260-
@code {
261-
private int currentCount = 0;
262-
263-
private void IncrementCount()
264-
{
265-
currentCount++;
266-
}
267-
}
268-
```
269-
270-
1. Set a breakpoint on the `currentCount++;` line in the `Counter2` component.
218+
1. In the server app, open the statically-rendered `Weather` component (`Components/Pages/Weather.razor`) and set a breakpoint anywhere in the `OnInitializedAsync` method.
271219
1. Select the **Start Debugging** button in the UI or press <kbd>F5</kbd> (**Start Debugging**) to run the app in the debugger.
272-
1. In the browser, navigate to the `Counter2` page at `/counter-2`. Wait a few seconds for the debug proxy to load and run. Select the **Click me** button to hit the breakpoint.
220+
1. In the browser, navigate to the `Weather` page at `/weather`. Wait a few seconds for the debug proxy to load and run. Application execution stops at the breakpoint.
273221
1. Select the **Continue** button in the UI or press <kbd>F5</kbd> (**Continue**) to continue execution.
274222

275223
Breakpoints are **not** hit during app startup before the debug proxy is running. This includes breakpoints in the `Program` file and breakpoints in the [`OnInitialized{Async}` lifecycle methods](xref:blazor/components/lifecycle#component-initialization-oninitializedasync) of components that are loaded by the first page requested from the app.
@@ -437,8 +385,8 @@ The additional options in the following table only apply to **hosted Blazor WebA
437385

438386
*The guidance in this section applies debugging Blazor WebAssembly apps in:*
439387

440-
* *Google Chrome running on Windows or macOS.*
441-
* *Microsoft Edge running on Windows.*
388+
* ***Google Chrome*** *running on Windows or macOS.*
389+
* ***Microsoft Edge** *running on Windows.*
442390

443391
1. Run the app in a command shell with `dotnet watch` (or `dotnet run`).
444392
1. Launch a browser and navigate to the app's URL.

aspnetcore/blazor/fundamentals/routing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ Constraint | Example | Example Matches | Invariant<br>culture<br>matching
372372
`decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | Yes
373373
`double` | `{weight:double}` | `1.234`, `-1,001.01e8` | Yes
374374
`float` | `{weight:float}` | `1.234`, `-1,001.01e8` | Yes
375-
`guid` | `{id:guid}` | `CD2C1638-1638-72D5-1638-DEADBEEF1638`, `{CD2C1638-1638-72D5-1638-DEADBEEF1638}` | No
375+
`guid` | `{id:guid}` | `00001111-aaaa-2222-bbbb-3333cccc4444`, `{00001111-aaaa-2222-bbbb-3333cccc4444}` | No
376376
`int` | `{id:int}` | `123456789`, `-123456789` | Yes
377377
`long` | `{ticks:long}` | `123456789`, `-123456789` | Yes
378378
`nonfile` | `{parameter:nonfile}` | Not `BlazorSample.styles.css`, not `favicon.ico` | Yes

aspnetcore/blazor/security/blazor-web-app-with-oidc.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The following <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConn
116116
* Client Id (`{CLIENT ID}`): `00001111-aaaa-2222-bbbb-3333cccc4444`
117117

118118
```csharp
119-
oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
119+
oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
120120
oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
121121
```
122122

@@ -363,7 +363,7 @@ The following <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConn
363363
* Scope configured for weather data from `MinimalApiJwt` (`{API NAME}`): `Weather.Get`
364364

365365
```csharp
366-
oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/4ba4de56-9cef-45d9-83fa-a4c18f9f5f0f/Weather.Get");
366+
oidcOptions.Scope.Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/Weather.Get");
367367
```
368368

369369
The preceding example pertains to an app registered in a tenant with an AAD B2C tenant type. If the app is registered in an ME-ID tenant, the App ID URI is different, thus the scope is different.
@@ -390,7 +390,7 @@ The following <xref:Microsoft.AspNetCore.Authentication.OpenIdConnect.OpenIdConn
390390
* Client Id (`{CLIENT ID}`): `00001111-aaaa-2222-bbbb-3333cccc4444`
391391

392392
```csharp
393-
oidcOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
393+
oidcOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
394394
oidcOptions.ClientId = "00001111-aaaa-2222-bbbb-3333cccc4444";
395395
```
396396

@@ -560,13 +560,13 @@ Configure the project in the <xref:Microsoft.AspNetCore.Authentication.JwtBearer
560560
Authority (`{AUTHORITY}`): `https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/` (uses Tenant ID `aaaabbbb-0000-cccc-1111-dddd2222eeee`)
561561

562562
```csharp
563-
jwtOptions.Authority = "https://login.microsoftonline.com/a3942615-d115-4eb7-bc84-9974abcf5064/v2.0/";
563+
jwtOptions.Authority = "https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/";
564564
```
565565

566566
The preceding example pertains to an app registered in a tenant with an AAD B2C tenant type. If the app is registered in an ME-ID tenant, the authority should match the issurer (`iss`) of the JWT returned by the identity provider:
567567

568568
```csharp
569-
jwtOptions.Authority = "https://sts.windows.net/a3942615-d115-4eb7-bc84-9974abcf5064/";
569+
jwtOptions.Authority = "https://sts.windows.net/aaaabbbb-0000-cccc-1111-dddd2222eeee/";
570570
```
571571

572572
### Minimal API for weather data

aspnetcore/blazor/security/includes/authorize-client-app.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
> If you don't have the authority to grant admin consent to the tenant in the last step of **API permissions** configuration because consent to use the app is delegated to users, then you must take the following additional steps:
33
>
44
> * The app must use a [trusted publisher domain](/entra/identity-platform/howto-configure-publisher-domain).
5-
> * In the **`Server`** app's configuration in the Azure portal, select **Expose an API**. Under **Authorized client applications**, select the button to **Add a client application**. Add the **`Client`** app's Application (client) ID (for example, `4369008b-21fa-427c-abaa-9b53bf58e538`).
5+
> * In the **`Server`** app's configuration in the Azure portal, select **Expose an API**. Under **Authorized client applications**, select the button to **Add a client application**. Add the **`Client`** app's Application (client) ID (for example, `11112222-bbbb-3333-cccc-4444dddd5555`).

aspnetcore/blazor/security/includes/troubleshoot-wasm.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ Example JWT decoded by the tool for an app that authenticates against Azure AAD
210210
"exp": 1610059429,
211211
"nbf": 1610055829,
212212
"ver": "1.0",
213-
"iss": "https://mysiteb2c.b2clogin.com/5cc15ea8-a296-4aa3-97e4-226dcc9ad298/v2.0/",
213+
"iss": "https://mysiteb2c.b2clogin.com/11112222-bbbb-3333-cccc-4444dddd5555/v2.0/",
214214
"sub": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
215215
"aud": "00001111-aaaa-2222-bbbb-3333cccc4444",
216-
"nonce": "b2641f54-8dc4-42ca-97ea-7f12ff4af871",
216+
"nonce": "bbbb0000-cccc-1111-dddd-2222eeee3333",
217217
"iat": 1610055829,
218218
"auth_time": 1610055822,
219219
"idp": "idp.com",

aspnetcore/blazor/security/webassembly/hosted-with-azure-active-directory-b2c.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ The output location specified with the `-o|--output` option creates a project fo
137137

138138
*The guidance in this section covers optionally populating `User.Identity.Name` with the value from the `name` claim.*
139139

140-
The **:::no-loc text="Server":::** app API populates `User.Identity.Name` with the value from the `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` claim type (for example, `2d64b3da-d9d5-42c6-9352-53d8df33d770@contoso.onmicrosoft.com`).
140+
The **:::no-loc text="Server":::** app API populates `User.Identity.Name` with the value from the `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` claim type (for example, `aaaabbbb-0000-cccc-1111-dddd2222eeee@contoso.onmicrosoft.com`).
141141

142142
To configure the app to receive the value from the `name` claim type:
143143

@@ -358,7 +358,7 @@ Example default access token scope:
358358

359359
```csharp
360360
options.ProviderOptions.DefaultAccessTokenScopes.Add(
361-
"https://contoso.onmicrosoft.com/41451fa7-82d9-4673-8fa5-69eff5a761fd/API.Access");
361+
"https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
362362
```
363363

364364
For more information, see the following sections of the *Additional scenarios* article:

aspnetcore/blazor/security/webassembly/hosted-with-microsoft-entra-id.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ The output location specified with the `-o|--output` option creates a project fo
141141

142142
*The guidance in this section covers optionally populating `User.Identity.Name` with the value from the `name` claim.*
143143

144-
The **:::no-loc text="Server":::** app API populates `User.Identity.Name` with the value from the `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` claim type (for example, `2d64b3da-d9d5-42c6-9352-53d8df33d770@contoso.onmicrosoft.com`).
144+
The **:::no-loc text="Server":::** app API populates `User.Identity.Name` with the value from the `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` claim type (for example, `bbbb0000-cccc-1111-dddd-2222eeee3333@contoso.onmicrosoft.com`).
145145

146146
To configure the app to receive the value from the `name` claim type:
147147

@@ -464,7 +464,7 @@ Instead of the App ID URI matching the format `api://{SERVER API APP CLIENT ID O
464464

465465
```csharp
466466
options.ProviderOptions.DefaultAccessTokenScopes
467-
.Add("https://contoso.onmicrosoft.com/41451fa7-82d9-4673-8fa5-69eff5a761fd/API.Access");
467+
.Add("https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444/API.Access");
468468
```
469469

470470
In the preceding scope, the App ID URI/audience is the `https://contoso.onmicrosoft.com/00001111-aaaa-2222-bbbb-3333cccc4444` portion of the value, which doesn't include a trailing slash (`/`) and doesn't include the scope name (`API.Access`).

aspnetcore/blazor/security/webassembly/microsoft-entra-id-groups-and-roles-net-5-to-7.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ When working with the default directory, follow the guidance in [Add app roles t
542542
],
543543
"description": "Administrators manage developers.",
544544
"displayName": "Admin",
545-
"id": "584e483a-7101-404b-9bb1-83bf9463e335",
545+
"id": "{ADMIN GUID}",
546546
"isEnabled": true,
547547
"lang": null,
548548
"origin": "Application",
@@ -554,7 +554,7 @@ When working with the default directory, follow the guidance in [Add app roles t
554554
],
555555
"description": "Developers write code.",
556556
"displayName": "Developer",
557-
"id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
557+
"id": "{DEVELOPER GUID}",
558558
"isEnabled": true,
559559
"lang": null,
560560
"origin": "Application",
@@ -563,8 +563,7 @@ When working with the default directory, follow the guidance in [Add app roles t
563563
],
564564
```
565565

566-
> [!NOTE]
567-
> You can generate GUIDs with an [online GUID generator program (Google search result for "guid generator")](https://www.google.com/search?q=guid+generator).
566+
For the `{ADMIN GUID}` and `{DEVELOPER GUID}` placeholders in the preceding example, you can generate GUIDs with an [online GUID generator (Google search result for "guid generator")](https://www.google.com/search?q=guid+generator).
568567

569568
To assign a role to a user (or group if you have a Premium tier Azure account):
570569

aspnetcore/blazor/security/webassembly/microsoft-entra-id-groups-and-roles.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ Take either of the following approaches add app roles in ME-ID:
282282
],
283283
"description": "Administrators manage developers.",
284284
"displayName": "Admin",
285-
"id": "584e483a-7101-404b-9bb1-83bf9463e335",
285+
"id": "{ADMIN GUID}",
286286
"isEnabled": true,
287287
"lang": null,
288288
"origin": "Application",
@@ -294,7 +294,7 @@ Take either of the following approaches add app roles in ME-ID:
294294
],
295295
"description": "Developers write code.",
296296
"displayName": "Developer",
297-
"id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
297+
"id": "{DEVELOPER GUID}",
298298
"isEnabled": true,
299299
"lang": null,
300300
"origin": "Application",
@@ -303,8 +303,7 @@ Take either of the following approaches add app roles in ME-ID:
303303
],
304304
```
305305

306-
> [!NOTE]
307-
> You can generate GUIDs with an [online GUID generator program (Google search result for "guid generator")](https://www.google.com/search?q=guid+generator).
306+
For the `{ADMIN GUID}` and `{DEVELOPER GUID}` placeholders in the preceding example, you can generate GUIDs with an [online GUID generator (Google search result for "guid generator")](https://www.google.com/search?q=guid+generator).
308307

309308
To assign a role to a user (or group if you have a Premium tier Azure account):
310309

0 commit comments

Comments
 (0)