You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aspnetcore/blazor/blazor-ef-core.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -103,6 +103,14 @@ The grid, add, and view components use the "context-per-operation" pattern, wher
103
103
> [!NOTE]
104
104
> 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).
105
105
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
+
106
114
## Database access
107
115
108
116
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:
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.
168
168
169
169
:::moniker range="< aspnetcore-8.0"
170
170
171
171
Hosted Blazor WebAssembly:
172
172
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.
174
174
***:::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.
175
175
176
176
:::moniker-end
@@ -187,43 +187,17 @@ The example in this section assumes that you've created a Blazor Web App with an
187
187
188
188
1. Open the app.
189
189
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.
191
191
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.
192
192
1. In Visual Studio, inspect the value of the `currentCount` field in the **Locals** window.
193
193
1. Press <kbd>F5</kbd> to continue execution.
194
194
195
195
Breakpoints can also be hit in the server project in statically-rendered and interactively-rendered server-side components.
196
196
197
197
1. Stop the debugger.
198
-
1. Add the following component to the server app. The component applies the Interactive Server render mode (`InteractiveServer`).
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.
225
199
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.
227
201
1. Press <kbd>F5</kbd> to continue execution.
228
202
229
203
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
241
215
Breakpoints can also be hit in the server project.
242
216
243
217
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`).
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.
271
219
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.
273
221
1. Select the **Continue** button in the UI or press <kbd>F5</kbd> (**Continue**) to continue execution.
274
222
275
223
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
437
385
438
386
*The guidance in this section applies debugging Blazor WebAssembly apps in:*
439
387
440
-
**Google Chromerunning on Windows or macOS.*
441
-
**Microsoft Edgerunning on Windows.*
388
+
****Google Chrome****running on Windows or macOS.*
389
+
****Microsoft Edge***running on Windows.*
442
390
443
391
1. Run the app in a command shell with `dotnet watch` (or `dotnet run`).
444
392
1. Launch a browser and navigate to the app's URL.
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
390
390
* Client Id (`{CLIENT ID}`): `00001111-aaaa-2222-bbbb-3333cccc4444`
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:
Copy file name to clipboardExpand all lines: aspnetcore/blazor/security/includes/authorize-client-app.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,4 +2,4 @@
2
2
> 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:
3
3
>
4
4
> * 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`).
Copy file name to clipboardExpand all lines: aspnetcore/blazor/security/webassembly/hosted-with-azure-active-directory-b2c.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -137,7 +137,7 @@ The output location specified with the `-o|--output` option creates a project fo
137
137
138
138
*The guidance in this section covers optionally populating `User.Identity.Name` with the value from the `name` claim.*
139
139
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`).
141
141
142
142
To configure the app to receive the value from the `name` claim type:
143
143
@@ -358,7 +358,7 @@ Example default access token scope:
Copy file name to clipboardExpand all lines: aspnetcore/blazor/security/webassembly/hosted-with-microsoft-entra-id.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -141,7 +141,7 @@ The output location specified with the `-o|--output` option creates a project fo
141
141
142
142
*The guidance in this section covers optionally populating `User.Identity.Name` with the value from the `name` claim.*
143
143
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`).
145
145
146
146
To configure the app to receive the value from the `name` claim type:
147
147
@@ -464,7 +464,7 @@ Instead of the App ID URI matching the format `api://{SERVER API APP CLIENT ID O
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`).
@@ -554,7 +554,7 @@ When working with the default directory, follow the guidance in [Add app roles t
554
554
],
555
555
"description": "Developers write code.",
556
556
"displayName": "Developer",
557
-
"id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
557
+
"id": "{DEVELOPER GUID}",
558
558
"isEnabled": true,
559
559
"lang": null,
560
560
"origin": "Application",
@@ -563,8 +563,7 @@ When working with the default directory, follow the guidance in [Add app roles t
563
563
],
564
564
```
565
565
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).
568
567
569
568
To assign a role to a user (or group if you have a Premium tier Azure account):
@@ -294,7 +294,7 @@ Take either of the following approaches add app roles in ME-ID:
294
294
],
295
295
"description": "Developers write code.",
296
296
"displayName": "Developer",
297
-
"id": "82770d35-2a93-4182-b3f5-3d7bfe9dfe46",
297
+
"id": "{DEVELOPER GUID}",
298
298
"isEnabled": true,
299
299
"lang": null,
300
300
"origin": "Application",
@@ -303,8 +303,7 @@ Take either of the following approaches add app roles in ME-ID:
303
303
],
304
304
```
305
305
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).
308
307
309
308
To assign a role to a user (or group if you have a Premium tier Azure account):
0 commit comments