From 495cdada15febd18f65497c368c782a975faa9b5 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Tue, 8 Nov 2022 06:15:47 -0600
Subject: [PATCH] Blazor .NET 7 release work
---
aspnetcore/blazor/advanced-scenarios.md | 30 +-
aspnetcore/blazor/blazor-server-ef-core.md | 114 +-
aspnetcore/blazor/call-web-api.md | 86 +-
.../blazor/components/built-in-components.md | 36 +-
.../cascading-values-and-parameters.md | 166 +-
.../blazor/components/class-libraries.md | 2 +-
.../blazor/components/control-head-content.md | 55 +-
aspnetcore/blazor/components/css-isolation.md | 2 +-
aspnetcore/blazor/components/data-binding.md | 408 +-
.../blazor/components/dynamiccomponent.md | 34 +-
.../blazor/components/event-handling.md | 492 +--
aspnetcore/blazor/components/index.md | 3616 ++++++++---------
aspnetcore/blazor/components/layouts.md | 90 +-
aspnetcore/blazor/components/lifecycle.md | 138 +-
.../prerendering-and-integration.md | 1724 ++++----
aspnetcore/blazor/components/rendering.md | 50 +-
.../blazor/components/templated-components.md | 52 +-
.../blazor/components/virtualization.md | 312 +-
aspnetcore/blazor/debug.md | 150 +-
aspnetcore/blazor/file-downloads.md | 22 +-
aspnetcore/blazor/file-uploads.md | 114 +-
.../blazor/forms-and-input-components.md | 1592 ++++----
.../blazor/fundamentals/configuration.md | 2 +-
.../fundamentals/dependency-injection.md | 460 +--
.../blazor/fundamentals/environments.md | 96 +-
.../blazor/fundamentals/handle-errors.md | 1010 ++---
aspnetcore/blazor/fundamentals/index.md | 2 +-
aspnetcore/blazor/fundamentals/logging.md | 970 ++---
aspnetcore/blazor/fundamentals/routing.md | 1276 +++---
aspnetcore/blazor/fundamentals/signalr.md | 256 +-
aspnetcore/blazor/fundamentals/startup.md | 142 +-
.../blazor/fundamentals/static-files.md | 2 +-
.../blazor/globalization-localization.md | 430 +-
.../host-and-deploy/configure-linker.md | 2 +-
.../host-and-deploy/configure-trimmer.md | 2 +-
aspnetcore/blazor/host-and-deploy/index.md | 2 +-
.../multiple-hosted-webassembly.md | 2 +-
aspnetcore/blazor/host-and-deploy/server.md | 490 +--
.../webassembly-deployment-layout.md | 2 +-
.../blazor/host-and-deploy/webassembly.md | 760 ++--
aspnetcore/blazor/hosting-models.md | 216 +-
aspnetcore/blazor/hybrid/class-libraries.md | 10 +-
aspnetcore/blazor/hybrid/developer-tools.md | 2 +-
aspnetcore/blazor/hybrid/index.md | 2 +-
.../blazor/hybrid/reuse-razor-components.md | 2 +-
aspnetcore/blazor/hybrid/routing.md | 162 +-
aspnetcore/blazor/hybrid/security/index.md | 2 +-
.../security/security-considerations.md | 2 +-
aspnetcore/blazor/hybrid/static-files.md | 2 +-
aspnetcore/blazor/hybrid/tutorials/index.md | 2 +-
aspnetcore/blazor/hybrid/tutorials/maui.md | 2 +-
.../blazor/hybrid/tutorials/windows-forms.md | 2 +-
aspnetcore/blazor/hybrid/tutorials/wpf.md | 2 +-
aspnetcore/blazor/images.md | 16 +-
aspnetcore/blazor/index.md | 2 +-
.../call-dotnet-from-javascript.md | 1536 +++----
.../call-javascript-from-dotnet.md | 1058 ++---
.../import-export-interop.md | 2 +-
.../javascript-interoperability/index.md | 122 +-
aspnetcore/blazor/performance.md | 316 +-
aspnetcore/blazor/progressive-web-app.md | 367 +-
aspnetcore/blazor/project-structure.md | 106 +-
.../security/content-security-policy.md | 76 +-
aspnetcore/blazor/security/index.md | 212 +-
.../security/server/additional-scenarios.md | 2 +-
aspnetcore/blazor/security/server/index.md | 38 +-
.../security/server/threat-mitigation.md | 2 +-
.../webassembly/additional-scenarios.md | 370 +-
...azure-active-directory-groups-and-roles.md | 28 +-
.../blazor/security/webassembly/graph-api.md | 2 +-
.../hosted-with-azure-active-directory-b2c.md | 128 +-
.../hosted-with-azure-active-directory.md | 100 +-
.../hosted-with-identity-server.md | 736 ++--
.../blazor/security/webassembly/index.md | 108 +-
.../standalone-with-authentication-library.md | 18 +-
...ndalone-with-azure-active-directory-b2c.md | 70 +-
.../standalone-with-azure-active-directory.md | 42 +-
.../standalone-with-microsoft-accounts.md | 42 +-
aspnetcore/blazor/state-management.md | 461 ++-
aspnetcore/blazor/supported-platforms.md | 30 +-
aspnetcore/blazor/test.md | 2 +-
aspnetcore/blazor/tooling.md | 556 +--
.../blazor/tutorials/build-a-blazor-app.md | 98 +-
aspnetcore/blazor/tutorials/index.md | 2 +-
aspnetcore/blazor/tutorials/signalr-blazor.md | 296 +-
.../webassembly-lazy-load-assemblies.md | 2 +-
.../blazor/webassembly-native-dependencies.md | 2 +-
87 files changed, 11695 insertions(+), 10852 deletions(-)
diff --git a/aspnetcore/blazor/advanced-scenarios.md b/aspnetcore/blazor/advanced-scenarios.md
index bdefb0851015..ebcb4dd5f7ba 100644
--- a/aspnetcore/blazor/advanced-scenarios.md
+++ b/aspnetcore/blazor/advanced-scenarios.md
@@ -5,7 +5,7 @@ description: Learn how to incorporate manual logic for building Blazor render tr
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/advanced-scenarios
---
# ASP.NET Core Blazor advanced scenarios (render tree construction)
@@ -15,7 +15,7 @@ This article describes the advanced scenario for building Blazor render trees ma
> [!WARNING]
> Use of to create components is an *advanced scenario*. A malformed component (for example, an unclosed markup tag) can result in undefined behavior. Undefined behavior includes broken content rendering, loss of app features, and ***compromised security***.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
## Manually build a render tree (`RenderTreeBuilder`)
@@ -25,7 +25,7 @@ Consider the following `PetDetails` component, which can be manually rendered in
`Shared/PetDetails.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
In the following `BuiltContent` component, the loop in the `CreateComponent` method generates three `PetDetails` components.
@@ -33,7 +33,7 @@ In methods wi
`Pages/BuiltContent.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
> [!WARNING]
> The types in allow processing of the *results* of rendering operations. These are internal details of the Blazor framework implementation. These types should be considered *unstable* and subject to change in future releases.
@@ -130,7 +130,7 @@ This is a trivial example. In more realistic cases with complex and deeply neste
:::moniker-end
-:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
+:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
## Manually build a render tree (`RenderTreeBuilder`)
@@ -140,7 +140,7 @@ Consider the following `PetDetails` component, which can be manually rendered in
`Shared/PetDetails.razor`:
-:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
+:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
In the following `BuiltContent` component, the loop in the `CreateComponent` method generates three `PetDetails` components.
@@ -148,7 +148,7 @@ In methods wi
`Pages/BuiltContent.razor`:
-:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
+:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
> [!WARNING]
> The types in allow processing of the *results* of rendering operations. These are internal details of the Blazor framework implementation. These types should be considered *unstable* and subject to change in future releases.
@@ -213,7 +213,7 @@ if (someFlag)
builder.AddContent(seq++, "Second");
```
-The first output is seen in the following table.
+The first output is reflected in the following table.
| Sequence | Type | Data |
| :------: | --------- | :----: |
@@ -245,7 +245,7 @@ This is a trivial example. In more realistic cases with complex and deeply neste
:::moniker-end
-:::moniker range="< aspnetcore-5.0"
+:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
## Manually build a render tree (`RenderTreeBuilder`)
@@ -255,7 +255,7 @@ Consider the following `PetDetails` component, which can be manually rendered in
`Shared/PetDetails.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
In the following `BuiltContent` component, the loop in the `CreateComponent` method generates three `PetDetails` components.
@@ -263,7 +263,7 @@ In methods wi
`Pages/BuiltContent.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
> [!WARNING]
> The types in allow processing of the *results* of rendering operations. These are internal details of the Blazor framework implementation. These types should be considered *unstable* and subject to change in future releases.
@@ -360,7 +360,7 @@ This is a trivial example. In more realistic cases with complex and deeply neste
:::moniker-end
-:::moniker range=">= aspnetcore-7.0"
+:::moniker range="< aspnetcore-5.0"
## Manually build a render tree (`RenderTreeBuilder`)
@@ -370,7 +370,7 @@ Consider the following `PetDetails` component, which can be manually rendered in
`Shared/PetDetails.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Shared/advanced-scenarios/PetDetails.razor":::
In the following `BuiltContent` component, the loop in the `CreateComponent` method generates three `PetDetails` components.
@@ -378,7 +378,7 @@ In methods wi
`Pages/BuiltContent.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/advanced-scenarios/BuiltContent.razor" highlight="6,16-24,28":::
> [!WARNING]
> The types in allow processing of the *results* of rendering operations. These are internal details of the Blazor framework implementation. These types should be considered *unstable* and subject to change in future releases.
@@ -443,7 +443,7 @@ if (someFlag)
builder.AddContent(seq++, "Second");
```
-The first output is reflected in the following table.
+The first output is seen in the following table.
| Sequence | Type | Data |
| :------: | --------- | :----: |
diff --git a/aspnetcore/blazor/blazor-server-ef-core.md b/aspnetcore/blazor/blazor-server-ef-core.md
index a780247c7a7e..da7325e7cb3d 100644
--- a/aspnetcore/blazor/blazor-server-ef-core.md
+++ b/aspnetcore/blazor/blazor-server-ef-core.md
@@ -5,14 +5,14 @@ description: Learn how to use Entity Framework Core (EF Core) in Blazor Server a
monikerRange: '>= aspnetcore-3.1'
ms.author: jeliknes
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/blazor-server-ef-core
---
# ASP.NET Core Blazor Server with Entity Framework Core (EF Core)
This article explains how to use [Entity Framework Core (EF Core)](/ef/core/) in Blazor Server apps.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
Blazor Server is a stateful app framework. The app maintains an ongoing connection to the server, and the user's state is held in the server's memory in a *circuit*. One example of user state is data held in [dependency injection (DI)](xref:fundamentals/dependency-injection) service instances that are scoped to the circuit. The unique application model that Blazor Server provides requires a special approach to use Entity Framework Core.
@@ -27,7 +27,7 @@ The sample app was built as a reference for Blazor Server apps that use EF Core.
The sample uses a local [SQLite](https://www.sqlite.org/index.html) database so that it can be used on any platform. The sample also configures database logging to show the SQL queries that are generated. This is configured in `appsettings.Development.json`:
-:::code language="json" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/appsettings.Development.json" highlight="8":::
+:::code language="json" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/appsettings.Development.json" highlight="8":::
The grid, add, and view components use the "context-per-operation" pattern, where a context is created for each operation. The edit component uses the "context-per-component" pattern, where a context is created for each component.
@@ -80,8 +80,6 @@ The following recommendations are designed to provide a consistent approach to u
* For longer-lived operations that take advantage of EF Core's [change tracking](/ef/core/querying/tracking) or [concurrency control](/ef/core/saving/concurrency), [scope the context to the lifetime of the component](#scope-to-the-component-lifetime).
-## New `DbContext` instances
-
The fastest way to create a new instance is by using `new` to create a new instance. However, there are scenarios that require resolving additional dependencies:
* Using [`DbContextOptions`](/ef/core/miscellaneous/configuring-dbcontext#configuring-dbcontextoptions) to configure the context.
@@ -91,11 +89,11 @@ The recommended approach to create a new ` is injected into the component:
+In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/7.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
```razor
@inject IDbContextFactory DbFactory
@@ -103,10 +101,10 @@ In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samp
A `DbContext` is created using the factory (`DbFactory`) to delete a contact in the `DeleteContactAsync` method:
-:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/Index.razor" id="snippet1":::
> [!NOTE]
-> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
+> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/6.0/BlazorServerEFCoreSample/Pages/Index.razor).
## Scope to the component lifetime
@@ -120,11 +118,11 @@ You can use the factory to create a context and track it for the lifetime of the
The sample app ensures the context is disposed when the component is disposed:
-:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/EditContact.razor" id="snippet1":::
Finally, [`OnInitializedAsync`](xref:blazor/components/lifecycle) is overridden to create a new context. In the sample app, [`OnInitializedAsync`](xref:blazor/components/lifecycle) loads the contact in the same method:
-:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
+:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/EditContact.razor" id="snippet2":::
## Enable sensitive data logging
@@ -150,7 +148,7 @@ We recommend only enabling [!NOTE]
-> 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](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/blazor/samples/).
+> 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](https://github.com/dotnet/blazor-samples).
## Database access
@@ -229,11 +227,11 @@ The recommended approach to create a new ` is injected into the component:
+In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
```razor
@inject IDbContextFactory DbFactory
@@ -241,10 +239,10 @@ In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samp
A `DbContext` is created using the factory (`DbFactory`) to delete a contact in the `DeleteContactAsync` method:
-:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
> [!NOTE]
-> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
+> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
## Scope to the component lifetime
@@ -258,11 +256,11 @@ You can use the factory to create a context and track it for the lifetime of the
The sample app ensures the context is disposed when the component is disposed:
-:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
Finally, [`OnInitializedAsync`](xref:blazor/components/lifecycle) is overridden to create a new context. In the sample app, [`OnInitializedAsync`](xref:blazor/components/lifecycle) loads the contact in the same method:
-:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
+:::code language="csharp" source="~/../blazor-samples/6.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
## Enable sensitive data logging
@@ -288,7 +286,7 @@ We recommend only enabling 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 extension for ASP.NET Core apps that registers the context as a *scoped* service by default. In Blazor Server apps, this can be problematic because the instance is shared across components within the user's circuit. isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate for these reasons:
+EF Core relies on a 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 extension for ASP.NET Core apps that registers the context as a *scoped* service by default. In Blazor Server apps, scoped service registrations can be problematic because the instance is shared across components within the user's circuit. isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate for these reasons:
* **Singleton** shares state across all users of the app and leads to inappropriate concurrent use.
* **Scoped** (the default) poses a similar issue between components for the same user.
@@ -363,22 +361,15 @@ The fastest way to create a new i
* Using [`DbContextOptions`](/ef/core/miscellaneous/configuring-dbcontext#configuring-dbcontextoptions) to configure the context.
* Using a connection string per , such as when you use [ASP.NET Core's Identity model](xref:security/authentication/customize_identity_model). For more information, see [Multi-tenancy (EF Core documentation)](/ef/core/miscellaneous/multitenancy).
-The recommended approach to create a new with dependencies is to use a factory. The sample app implements its own factory in `Data/DbContextFactory.cs`.
-
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Data/DbContextFactory.cs":::
-
-In the preceding factory:
-
-* satisfies any dependencies via the service provider.
-* `IDbContextFactory` is available in EF Core ASP.NET Core 5.0 or later, so the interface is [implemented in the sample app for ASP.NET Core 3.x](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Data/IDbContextFactory.cs).
+The recommended approach to create a new with dependencies is to use a factory. EF Core 5.0 or later provides a built-in factory for creating new contexts.
-The following example configures [SQLite](https://www.sqlite.org/index.html) and enables data logging. The code uses an extension method to configure the database factory for DI and provide default options:
+The following example configures [SQLite](https://www.sqlite.org/index.html) and enables data logging. The code uses an extension method (`AddDbContextFactory`) to configure the database factory for DI and provide default options:
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Startup.cs" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Startup.cs" id="snippet1":::
The factory is injected into components and used to create new `DbContext` instances.
-In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
+In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
```razor
@inject IDbContextFactory DbFactory
@@ -386,10 +377,10 @@ In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samp
A `DbContext` is created using the factory (`DbFactory`) to delete a contact in the `DeleteContactAsync` method:
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
> [!NOTE]
-> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
+> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
## Scope to the component lifetime
@@ -403,16 +394,11 @@ You can use the factory to create a context and track it for the lifetime of the
The sample app ensures the context is disposed when the component is disposed:
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
Finally, [`OnInitializedAsync`](xref:blazor/components/lifecycle) is overridden to create a new context. In the sample app, [`OnInitializedAsync`](xref:blazor/components/lifecycle) loads the contact in the same method:
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
-
-In the preceding example:
-
-* When `Busy` is set to `true`, asynchronous operations may begin. When `Busy` is set back to `false`, asynchronous operations should be finished.
-* Place additional error handling logic in a `catch` block.
+:::code language="csharp" source="~/../blazor-samples/5.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
## Enable sensitive data logging
@@ -438,7 +424,7 @@ We recommend only enabling [!NOTE]
-> 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](https://github.com/dotnet/blazor-samples).
+> 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](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/blazor/samples/).
## Database access
-EF Core relies on a 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 extension for ASP.NET Core apps that registers the context as a *scoped* service by default. In Blazor Server apps, scoped service registrations can be problematic because the instance is shared across components within the user's circuit. isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate for these reasons:
+EF Core relies on a 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 extension for ASP.NET Core apps that registers the context as a *scoped* service by default. In Blazor Server apps, this can be problematic because the instance is shared across components within the user's circuit. isn't thread safe and isn't designed for concurrent use. The existing lifetimes are inappropriate for these reasons:
* **Singleton** shares state across all users of the app and leads to inappropriate concurrent use.
* **Scoped** (the default) poses a similar issue between components for the same user.
@@ -506,20 +492,29 @@ The following recommendations are designed to provide a consistent approach to u
* For longer-lived operations that take advantage of EF Core's [change tracking](/ef/core/querying/tracking) or [concurrency control](/ef/core/saving/concurrency), [scope the context to the lifetime of the component](#scope-to-the-component-lifetime).
+## New `DbContext` instances
+
The fastest way to create a new instance is by using `new` to create a new instance. However, there are scenarios that require resolving additional dependencies:
* Using [`DbContextOptions`](/ef/core/miscellaneous/configuring-dbcontext#configuring-dbcontextoptions) to configure the context.
* Using a connection string per , such as when you use [ASP.NET Core's Identity model](xref:security/authentication/customize_identity_model). For more information, see [Multi-tenancy (EF Core documentation)](/ef/core/miscellaneous/multitenancy).
-The recommended approach to create a new with dependencies is to use a factory. EF Core 5.0 or later provides a built-in factory for creating new contexts.
+The recommended approach to create a new with dependencies is to use a factory. The sample app implements its own factory in `Data/DbContextFactory.cs`.
-The following example configures [SQLite](https://www.sqlite.org/index.html) and enables data logging. The code uses an extension method (`AddDbContextFactory`) to configure the database factory for DI and provide default options:
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Data/DbContextFactory.cs":::
-:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Program.cs" id="snippet1":::
+In the preceding factory:
+
+* satisfies any dependencies via the service provider.
+* `IDbContextFactory` is available in EF Core ASP.NET Core 5.0 or later, so the interface is [implemented in the sample app for ASP.NET Core 3.x](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Data/IDbContextFactory.cs).
+
+The following example configures [SQLite](https://www.sqlite.org/index.html) and enables data logging. The code uses an extension method to configure the database factory for DI and provide default options:
+
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Startup.cs" id="snippet1":::
The factory is injected into components and used to create new `DbContext` instances.
-In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/7.0/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
+In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor), `IDbContextFactory` is injected into the component:
```razor
@inject IDbContextFactory DbFactory
@@ -527,10 +522,10 @@ In `Pages/Index.razor` of the [sample app](https://github.com/dotnet/blazor-samp
A `DbContext` is created using the factory (`DbFactory`) to delete a contact in the `DeleteContactAsync` method:
-:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/Index.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor" id="snippet1":::
> [!NOTE]
-> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/6.0/BlazorServerEFCoreSample/Pages/Index.razor).
+> `Filters` is an injected `IContactFilters`, and `Wrapper` is a [component reference](xref:blazor/components/index#capture-references-to-components) to the `GridWrapper` component. See the `Index` component (`Pages/Index.razor`) in the [sample app](https://github.com/dotnet/blazor-samples/blob/main/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/Index.razor).
## Scope to the component lifetime
@@ -544,11 +539,16 @@ You can use the factory to create a context and track it for the lifetime of the
The sample app ensures the context is disposed when the component is disposed:
-:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/EditContact.razor" id="snippet1":::
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet1":::
Finally, [`OnInitializedAsync`](xref:blazor/components/lifecycle) is overridden to create a new context. In the sample app, [`OnInitializedAsync`](xref:blazor/components/lifecycle) loads the contact in the same method:
-:::code language="csharp" source="~/../blazor-samples/7.0/BlazorServerEFCoreSample/Pages/EditContact.razor" id="snippet2":::
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorServerEFCoreSample/BlazorServerDbContextExample/Pages/EditContact.razor" id="snippet2":::
+
+In the preceding example:
+
+* When `Busy` is set to `true`, asynchronous operations may begin. When `Busy` is set back to `false`, asynchronous operations should be finished.
+* Place additional error handling logic in a `catch` block.
## Enable sensitive data logging
diff --git a/aspnetcore/blazor/call-web-api.md b/aspnetcore/blazor/call-web-api.md
index 669ffceb69e9..7a139f13ce7f 100644
--- a/aspnetcore/blazor/call-web-api.md
+++ b/aspnetcore/blazor/call-web-api.md
@@ -5,7 +5,7 @@ description: Learn how to call a web API from Blazor apps.
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/call-web-api
zone_pivot_groups: blazor-hosting-models
---
@@ -13,7 +13,7 @@ zone_pivot_groups: blazor-hosting-models
This article describes how to call a web API from a Blazor app.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
:::zone pivot="webassembly"
@@ -379,7 +379,7 @@ else
`Pages/TodoRequest.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
Blazor WebAssembly's implementation of uses [Fetch API](https://developer.mozilla.org/docs/Web/API/fetch). Fetch API allows the configuration of several [request-specific options](https://developer.mozilla.org/docs/Web/API/fetch#Parameters). Options can be configured with extension methods shown in the following table.
@@ -421,7 +421,7 @@ By default, ASP.NET Core apps use ports 5000 (HTTP) and 5001 (HTTPS). To run bot
`Pages/CallWebAPI.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
## Handle errors
@@ -640,7 +640,7 @@ Various network tools are publicly available for testing web API backend apps di
:::moniker-end
-:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
+:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
:::zone pivot="webassembly"
@@ -668,7 +668,7 @@ Use the following `TodoItem` class with this article's examples if you build the
public class TodoItem
{
public long Id { get; set; }
- public string Name { get; set; }
+ public string? Name { get; set; }
public bool IsComplete { get; set; }
}
```
@@ -739,7 +739,7 @@ else
}
@code {
- private TodoItem[] todoItems;
+ private TodoItem[]? todoItems;
protected override async Task OnInitializedAsync() =>
todoItems = await Http.GetFromJsonAsync("api/TodoItems");
@@ -762,7 +762,7 @@ In the following component code, `newItemName` is provided by a bound element of
@code {
- private string newItemName;
+ private string? newItemName;
private async Task AddItem()
{
@@ -782,7 +782,7 @@ var content = await response.Content.ReadFromJsonAsync();
sends an HTTP PUT request with JSON-encoded content.
-In the following component code, `editItem` values for `Name` and `IsCompleted` are provided by bound elements of the component. The item's `Id` is set when the item is selected in another part of the UI (not shown) and `EditItem` is called. The `SaveItem` method is triggered by selecting the `
@code {
- private WeatherForecast[] forecasts;
- private string exceptionMessage;
+ private WeatherForecast[]? forecasts;
+ private string? exceptionMessage;
protected override async Task OnInitializedAsync()
{
@@ -1143,10 +1143,10 @@ For more information, see .
A Blazor Server app doesn't include an service by default. Provide an to the app using the [`HttpClient` factory infrastructure](xref:fundamentals/http-requests).
-In `Startup.ConfigureServices` of `Startup.cs`:
+In `Program.cs`:
```csharp
-services.AddHttpClient();
+builder.Services.AddHttpClient();
```
The following Blazor Server Razor component makes a request to a web API for GitHub branches similar to the *Basic Usage* example in the article.
@@ -1243,8 +1243,6 @@ Various network tools are publicly available for testing web API backend apps di
[`HttpClientTest` assets in the `dotnet/aspnetcore` GitHub repository](https://github.com/dotnet/aspnetcore/tree/main/src/Components/test/testassets/BasicTestApp/HttpClientTest)
-[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
-
## Additional resources
:::zone pivot="webassembly"
@@ -1269,7 +1267,7 @@ Various network tools are publicly available for testing web API backend apps di
:::moniker-end
-:::moniker range="< aspnetcore-5.0"
+:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
:::zone pivot="webassembly"
@@ -1635,7 +1633,7 @@ else
`Pages/TodoRequest.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
Blazor WebAssembly's implementation of uses [Fetch API](https://developer.mozilla.org/docs/Web/API/fetch). Fetch API allows the configuration of several [request-specific options](https://developer.mozilla.org/docs/Web/API/fetch#Parameters). Options can be configured with extension methods shown in the following table.
@@ -1673,11 +1671,11 @@ app.UseCors(policy =>
Adjust the domains and ports of `WithOrigins` as needed for the Blazor app. For more information, see .
-By default, ASP.NET Core apps use ports 5000 (HTTP) and 5001 (HTTPS). To run both apps on the same machine at the same time for testing, use a different port for the web API app (for example, port 10000). For more information on setting the port, see .
+By default, ASP.NET Core apps use ports 5000 (HTTP) and 5001 (HTTPS). To run both apps on the same machine at the same time for testing, use a different port for the web API app (for example, port 10000). For more information on setting the port, see .
`Pages/CallWebAPI.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
## Handle errors
@@ -1891,14 +1889,14 @@ Various network tools are publicly available for testing web API backend apps di
*
*
*
-* [Kestrel HTTPS endpoint configuration](xref:fundamentals/servers/kestrel#endpoint-configuration)
+* [Kestrel HTTPS endpoint configuration](xref:fundamentals/servers/kestrel/endpoints)
* [Cross Origin Resource Sharing (CORS) at W3C](https://www.w3.org/TR/cors/)
:::zone-end
:::moniker-end
-:::moniker range=">= aspnetcore-7.0"
+:::moniker range="< aspnetcore-5.0"
:::zone pivot="webassembly"
@@ -1926,7 +1924,7 @@ Use the following `TodoItem` class with this article's examples if you build the
public class TodoItem
{
public long Id { get; set; }
- public string? Name { get; set; }
+ public string Name { get; set; }
public bool IsComplete { get; set; }
}
```
@@ -1997,7 +1995,7 @@ else
}
@code {
- private TodoItem[]? todoItems;
+ private TodoItem[] todoItems;
protected override async Task OnInitializedAsync() =>
todoItems = await Http.GetFromJsonAsync("api/TodoItems");
@@ -2020,7 +2018,7 @@ In the following component code, `newItemName` is provided by a bound element of
Add
@code {
- private string? newItemName;
+ private string newItemName;
private async Task AddItem()
{
@@ -2040,7 +2038,7 @@ var content = await response.Content.ReadFromJsonAsync();
sends an HTTP PUT request with JSON-encoded content.
-In the following component code, `editItem` values for `Name` and `IsCompleted` are provided by bound elements of the component. The item's `Id` is set when the item is selected in another part of the UI (not shown) and `EditItem` is called. The `SaveItem` method is triggered by selecting the `` element. Note that the following example doesn't show loading `todoItems` for brevity (see the [GET from JSON (`GetFromJsonAsync`)](#get-from-json-getfromjsonasync) section for an example of loading items).
+In the following component code, `editItem` values for `Name` and `IsCompleted` are provided by bound elements of the component. The item's `Id` is set when the item is selected in another part of the UI (not shown) and `EditItem` is called. The `SaveItem` method is triggered by selecting the `` element.
```razor
@using System.Net.Http
@@ -2053,7 +2051,7 @@ In the following component code, `editItem` values for `Name` and `IsCompleted`
Save
@code {
- private string? id;
+ private string id;
private TodoItem editItem = new TodoItem();
private void EditItem(long id)
@@ -2149,7 +2147,7 @@ else
}
@code {
- private WeatherForecast[]? forecasts;
+ private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
@@ -2249,7 +2247,7 @@ else
}
@code {
- private WeatherForecast[]? forecasts;
+ private WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
@@ -2264,7 +2262,7 @@ else
`Pages/TodoRequest.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/call-web-api/TodoRequest.razor":::
Blazor WebAssembly's implementation of uses [Fetch API](https://developer.mozilla.org/docs/Web/API/fetch). Fetch API allows the configuration of several [request-specific options](https://developer.mozilla.org/docs/Web/API/fetch#Parameters). Options can be configured with extension methods shown in the following table.
@@ -2291,7 +2289,7 @@ For more information on Fetch API options, see [MDN web docs: WindowOrWorkerGlob
The following example calls a web API. The example requires a running web API based on the sample app described by the article. This example makes requests to the web API at `https://localhost:10000/api/TodoItems`. If a different web API address is used, update the `ServiceEndpoint` constant value in the component's `@code` block.
-The following example makes a [cross-origin resource sharing (CORS)](xref:security/cors) request from `http://localhost:5000` or `https://localhost:5001` to the web API. Add the following CORS middleware configuration to the web API's service's `Program.cs` file:
+The following example makes a [cross-origin resource sharing (CORS)](xref:security/cors) request from `http://localhost:5000` or `https://localhost:5001` to the web API. Add the following CORS middleware configuration to the web API's service's `Startup.Configure` method:
```csharp
app.UseCors(policy =>
@@ -2302,11 +2300,11 @@ app.UseCors(policy =>
Adjust the domains and ports of `WithOrigins` as needed for the Blazor app. For more information, see .
-By default, ASP.NET Core apps use ports 5000 (HTTP) and 5001 (HTTPS). To run both apps on the same machine at the same time for testing, use a different port for the web API app (for example, port 10000). For more information on setting the port, see .
+By default, ASP.NET Core apps use ports 5000 (HTTP) and 5001 (HTTPS). To run both apps on the same machine at the same time for testing, use a different port for the web API app (for example, port 10000). For more information on setting the port, see .
`Pages/CallWebAPI.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/call-web-api/CallWebAPI.razor":::
## Handle errors
@@ -2354,8 +2352,8 @@ else
@code {
- private WeatherForecast[]? forecasts;
- private string? exceptionMessage;
+ private WeatherForecast[] forecasts;
+ private string exceptionMessage;
protected override async Task OnInitializedAsync()
{
@@ -2401,10 +2399,10 @@ For more information, see .
A Blazor Server app doesn't include an service by default. Provide an to the app using the [`HttpClient` factory infrastructure](xref:fundamentals/http-requests).
-In `Program.cs`:
+In `Startup.ConfigureServices` of `Startup.cs`:
```csharp
-builder.Services.AddHttpClient();
+services.AddHttpClient();
```
The following Blazor Server Razor component makes a request to a web API for GitHub branches similar to the *Basic Usage* example in the article.
@@ -2501,6 +2499,8 @@ Various network tools are publicly available for testing web API backend apps di
[`HttpClientTest` assets in the `dotnet/aspnetcore` GitHub repository](https://github.com/dotnet/aspnetcore/tree/main/src/Components/test/testassets/BasicTestApp/HttpClientTest)
+[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)]
+
## Additional resources
:::zone pivot="webassembly"
@@ -2518,7 +2518,7 @@ Various network tools are publicly available for testing web API backend apps di
*
*
*
-* [Kestrel HTTPS endpoint configuration](xref:fundamentals/servers/kestrel/endpoints)
+* [Kestrel HTTPS endpoint configuration](xref:fundamentals/servers/kestrel#endpoint-configuration)
* [Cross Origin Resource Sharing (CORS) at W3C](https://www.w3.org/TR/cors/)
:::zone-end
diff --git a/aspnetcore/blazor/components/built-in-components.md b/aspnetcore/blazor/components/built-in-components.md
index 8aea1a43b7c1..12d55503f159 100644
--- a/aspnetcore/blazor/components/built-in-components.md
+++ b/aspnetcore/blazor/components/built-in-components.md
@@ -5,14 +5,14 @@ description: Find information on Razor components provided by the Blazor framewo
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 06/09/2022
+ms.date: 11/08/2022
uid: blazor/components/built-in-components
---
# ASP.NET Core built-in Razor components
This article lists the Razor components that are provided by the Blazor framework.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
The following built-in Razor components are provided by the Blazor framework:
@@ -39,20 +39,28 @@ The following built-in Razor components are provided by the Blazor framework:
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
* [`NavMenu`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
* [`PageTitle`](xref:blazor/components/control-head-content)
+* [`QuickGrid`†](xref:blazor/components/index#quickgrid-component)
* [`Router`](xref:blazor/fundamentals/routing#route-templates)
* [`RouteView`](xref:blazor/fundamentals/routing#route-templates)
* [`Virtualize`](xref:blazor/components/virtualization)
+†Currently, the component is prerelease, experimental, unsupported, and not recommended for production apps.
+
:::moniker-end
-:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
+:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
-The following built-in Razor components are provided by ASP.NET Core:
+The following built-in Razor components are provided by the Blazor framework:
* [`App`](xref:blazor/project-structure)
* [`Authentication`](xref:blazor/security/webassembly/index#authentication-component)
* [`AuthorizeView`](xref:blazor/security/index#authorizeview-component)
* [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component)
+* [`DynamicComponent`](xref:blazor/components/dynamiccomponent)
+* [`ErrorBoundary`](xref:blazor/fundamentals/handle-errors#error-boundaries)
+* [`FocusOnNavigate`](xref:blazor/fundamentals/routing#focus-an-element-on-navigation)
+* [`HeadContent`](xref:blazor/components/control-head-content)
+* [`HeadOutlet`](xref:blazor/components/control-head-content)
* [`InputCheckbox`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputDate`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputFile`](xref:blazor/file-uploads)
@@ -66,15 +74,16 @@ The following built-in Razor components are provided by ASP.NET Core:
* [`MainLayout`](xref:blazor/components/layouts#mainlayout-component)
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
* [`NavMenu`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
+* [`PageTitle`](xref:blazor/components/control-head-content)
* [`Router`](xref:blazor/fundamentals/routing#route-templates)
* [`RouteView`](xref:blazor/fundamentals/routing#route-templates)
* [`Virtualize`](xref:blazor/components/virtualization)
:::moniker-end
-:::moniker range="< aspnetcore-5.0"
+:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
-The following built-in Razor components are provided by the Blazor framework:
+The following built-in Razor components are provided by ASP.NET Core:
* [`App`](xref:blazor/project-structure)
* [`Authentication`](xref:blazor/security/webassembly/index#authentication-component)
@@ -82,6 +91,7 @@ The following built-in Razor components are provided by the Blazor framework:
* [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component)
* [`InputCheckbox`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputDate`](xref:blazor/forms-and-input-components#built-in-input-components)
+* [`InputFile`](xref:blazor/file-uploads)
* [`InputNumber`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputRadio`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputRadioGroup`](xref:blazor/forms-and-input-components#built-in-input-components)
@@ -94,10 +104,11 @@ The following built-in Razor components are provided by the Blazor framework:
* [`NavMenu`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
* [`Router`](xref:blazor/fundamentals/routing#route-templates)
* [`RouteView`](xref:blazor/fundamentals/routing#route-templates)
+* [`Virtualize`](xref:blazor/components/virtualization)
:::moniker-end
-:::moniker range=">= aspnetcore-7.0"
+:::moniker range="< aspnetcore-5.0"
The following built-in Razor components are provided by the Blazor framework:
@@ -105,14 +116,8 @@ The following built-in Razor components are provided by the Blazor framework:
* [`Authentication`](xref:blazor/security/webassembly/index#authentication-component)
* [`AuthorizeView`](xref:blazor/security/index#authorizeview-component)
* [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component)
-* [`DynamicComponent`](xref:blazor/components/dynamiccomponent)
-* [`ErrorBoundary`](xref:blazor/fundamentals/handle-errors#error-boundaries)
-* [`FocusOnNavigate`](xref:blazor/fundamentals/routing#focus-an-element-on-navigation)
-* [`HeadContent`](xref:blazor/components/control-head-content)
-* [`HeadOutlet`](xref:blazor/components/control-head-content)
* [`InputCheckbox`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputDate`](xref:blazor/forms-and-input-components#built-in-input-components)
-* [`InputFile`](xref:blazor/file-uploads)
* [`InputNumber`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputRadio`](xref:blazor/forms-and-input-components#built-in-input-components)
* [`InputRadioGroup`](xref:blazor/forms-and-input-components#built-in-input-components)
@@ -123,12 +128,7 @@ The following built-in Razor components are provided by the Blazor framework:
* [`MainLayout`](xref:blazor/components/layouts#mainlayout-component)
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
* [`NavMenu`](xref:blazor/fundamentals/routing#navlink-and-navmenu-components)
-* [`PageTitle`](xref:blazor/components/control-head-content)
-* [`QuickGrid`†](xref:blazor/components/index#quickgrid-component)
* [`Router`](xref:blazor/fundamentals/routing#route-templates)
* [`RouteView`](xref:blazor/fundamentals/routing#route-templates)
-* [`Virtualize`](xref:blazor/components/virtualization)
-
-†Currently, the component is prerelease, experimental, unsupported, and not recommended for production apps.
:::moniker-end
diff --git a/aspnetcore/blazor/components/cascading-values-and-parameters.md b/aspnetcore/blazor/components/cascading-values-and-parameters.md
index 614e20384d12..170f9adfe97f 100644
--- a/aspnetcore/blazor/components/cascading-values-and-parameters.md
+++ b/aspnetcore/blazor/components/cascading-values-and-parameters.md
@@ -5,14 +5,14 @@ description: Learn how to flow data from an ancestor Razor component to descende
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/components/cascading-values-and-parameters
---
# ASP.NET Core Blazor cascading values and parameters
This article explains how to flow data from an ancestor Razor component to descendent components.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
*Cascading values and parameters* provide a convenient way to flow data down a component hierarchy from an ancestor component to any number of descendent components. Unlike [Component parameters](xref:blazor/components/index#component-parameters), cascading values and parameters don't require an attribute assignment for each descendent component where the data is consumed. Cascading values and parameters also allow components to coordinate with each other across a component hierarchy.
@@ -29,13 +29,13 @@ The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses`
`UIThemeClasses/ThemeInfo.cs`:
-:::code language="csharp" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
+:::code language="csharp" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
The following [layout component](xref:blazor/components/layouts) specifies theme information (`ThemeInfo`) as a cascading value for all components that make up the layout body of the property. `ButtonClass` is assigned a value of [`btn-success`](https://getbootstrap.com/docs/5.0/components/buttons/), which is a Bootstrap button style. Any descendent component in the component hierarchy can use the `ButtonClass` property through the `ThemeInfo` cascading value.
`Shared/MainLayout.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,10-14,19":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/MainLayout.razor":::
## `[CascadingParameter]` attribute
@@ -45,7 +45,7 @@ The following component binds the `ThemeInfo` cascading value to a cascading par
`Pages/ThemedCounter.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor":::
Similar to a regular component parameter, components accepting a cascading parameter are rerendered when the cascading value is changed. For instance, configuring a different theme instance causes the `ThemedCounter` component from the [`CascadingValue` component](#cascadingvalue-component) section to rerender:
@@ -53,10 +53,14 @@ Similar to a regular component parameter, components accepting a cascading param
```razor
+
+
Dark mode
@@ -256,7 +260,7 @@ The following `ExampleTabSet` component uses the `TabSet` component, which conta
:::moniker-end
-:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
+:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
*Cascading values and parameters* provide a convenient way to flow data down a component hierarchy from an ancestor component to any number of descendent components. Unlike [Component parameters](xref:blazor/components/index#component-parameters), cascading values and parameters don't require an attribute assignment for each descendent component where the data is consumed. Cascading values and parameters also allow components to coordinate with each other across a component hierarchy.
@@ -273,13 +277,13 @@ The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses`
`UIThemeClasses/ThemeInfo.cs`:
-:::code language="csharp" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
+:::code language="csharp" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
The following [layout component](xref:blazor/components/layouts) specifies theme information (`ThemeInfo`) as a cascading value for all components that make up the layout body of the property. `ButtonClass` is assigned a value of [`btn-success`](https://getbootstrap.com/docs/5.0/components/buttons/), which is a Bootstrap button style. Any descendent component in the component hierarchy can use the `ButtonClass` property through the `ThemeInfo` cascading value.
`Shared/MainLayout.razor`:
-:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,10-14,19":::
+:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,10-14,19":::
## `[CascadingParameter]` attribute
@@ -289,7 +293,33 @@ The following component binds the `ThemeInfo` cascading value to a cascading par
`Pages/ThemedCounter.razor`:
-:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor" highlight="2,15-17,23-24":::
+:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor":::
+
+Similar to a regular component parameter, components accepting a cascading parameter are rerendered when the cascading value is changed. For instance, configuring a different theme instance causes the `ThemedCounter` component from the [`CascadingValue` component](#cascadingvalue-component) section to rerender:
+
+`Shared/MainLayout.razor`:
+
+```razor
+
+
+
+ @Body
+
+
+ Dark mode
+
+
+@code {
+ private ThemeInfo theme = new() { ButtonClass = "btn-success" };
+
+ private void ChangeToDarkTheme()
+ {
+ theme = new() { ButtonClass = "btn-darkmode-success" };
+ }
+}
+```
+
+ can be used to indicate that a cascading parameter doesn't change after initialization.
## Cascade multiple values
@@ -305,26 +335,22 @@ In the following example, two [`CascadingValue`](xref:Microsoft.AspNetCore.Compo
@code {
- private CascadingType parentCascadeParameter1;
+ private CascadingType? parentCascadeParameter1;
[Parameter]
- public CascadingType ParentCascadeParameter2 { get; set; }
-
- ...
+ public CascadingType? ParentCascadeParameter2 { get; set; }
}
```
In a descendant component, the cascaded parameters receive their cascaded values from the ancestor component by :
```razor
-...
-
@code {
[CascadingParameter(Name = "CascadeParam1")]
- protected CascadingType ChildCascadeParameter1 { get; set; }
-
+ protected CascadingType? ChildCascadeParameter1 { get; set; }
+
[CascadingParameter(Name = "CascadeParam2")]
- protected CascadingType ChildCascadeParameter2 { get; set; }
+ protected CascadingType? ChildCascadeParameter2 { get; set; }
}
```
@@ -379,13 +405,13 @@ Child `Tab` components aren't explicitly passed as parameters to the `TabSet`. I
@code {
[Parameter]
- public RenderFragment ChildContent { get; set; }
+ public RenderFragment? ChildContent { get; set; }
- public ITab ActiveTab { get; private set; }
+ public ITab? ActiveTab { get; private set; }
public void AddTab(ITab tab)
{
- if (ActiveTab == null)
+ if (ActiveTab is null)
{
SetActiveTab(tab);
}
@@ -418,25 +444,25 @@ Descendent `Tab` components capture the containing `TabSet` as a cascading param
@code {
[CascadingParameter]
- public TabSet ContainerTabSet { get; set; }
+ public TabSet? ContainerTabSet { get; set; }
[Parameter]
- public string Title { get; set; }
+ public string? Title { get; set; }
[Parameter]
- public RenderFragment ChildContent { get; set; }
+ public RenderFragment? ChildContent { get; set; }
- private string TitleCssClass =>
- ContainerTabSet.ActiveTab == this ? "active" : null;
+ private string? TitleCssClass =>
+ ContainerTabSet?.ActiveTab == this ? "active" : null;
protected override void OnInitialized()
{
- ContainerTabSet.AddTab(this);
+ ContainerTabSet?.AddTab(this);
}
private void ActivateTab()
{
- ContainerTabSet.SetActiveTab(this);
+ ContainerTabSet?.SetActiveTab(this);
}
}
```
@@ -478,7 +504,7 @@ The following `ExampleTabSet` component uses the `TabSet` component, which conta
:::moniker-end
-:::moniker range="< aspnetcore-5.0"
+:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
*Cascading values and parameters* provide a convenient way to flow data down a component hierarchy from an ancestor component to any number of descendent components. Unlike [Component parameters](xref:blazor/components/index#component-parameters), cascading values and parameters don't require an attribute assignment for each descendent component where the data is consumed. Cascading values and parameters also allow components to coordinate with each other across a component hierarchy.
@@ -495,13 +521,13 @@ The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses`
`UIThemeClasses/ThemeInfo.cs`:
-:::code language="csharp" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
+:::code language="csharp" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
The following [layout component](xref:blazor/components/layouts) specifies theme information (`ThemeInfo`) as a cascading value for all components that make up the layout body of the property. `ButtonClass` is assigned a value of [`btn-success`](https://getbootstrap.com/docs/5.0/components/buttons/), which is a Bootstrap button style. Any descendent component in the component hierarchy can use the `ButtonClass` property through the `ThemeInfo` cascading value.
`Shared/MainLayout.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,9-13,17":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,10-14,19":::
## `[CascadingParameter]` attribute
@@ -511,7 +537,7 @@ The following component binds the `ThemeInfo` cascading value to a cascading par
`Pages/ThemedCounter.razor`:
-:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/ThemedCounter.razor" highlight="2,15-17,23-24":::
+:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor" highlight="2,15-17,23-24":::
## Cascade multiple values
@@ -700,7 +726,7 @@ The following `ExampleTabSet` component uses the `TabSet` component, which conta
:::moniker-end
-:::moniker range=">= aspnetcore-7.0"
+:::moniker range="< aspnetcore-5.0"
*Cascading values and parameters* provide a convenient way to flow data down a component hierarchy from an ancestor component to any number of descendent components. Unlike [Component parameters](xref:blazor/components/index#component-parameters), cascading values and parameters don't require an attribute assignment for each descendent component where the data is consumed. Cascading values and parameters also allow components to coordinate with each other across a component hierarchy.
@@ -717,13 +743,13 @@ The following `ThemeInfo` C# class is placed in a folder named `UIThemeClasses`
`UIThemeClasses/ThemeInfo.cs`:
-:::code language="csharp" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
+:::code language="csharp" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/UIThemeClasses/ThemeInfo.cs":::
The following [layout component](xref:blazor/components/layouts) specifies theme information (`ThemeInfo`) as a cascading value for all components that make up the layout body of the property. `ButtonClass` is assigned a value of [`btn-success`](https://getbootstrap.com/docs/5.0/components/buttons/), which is a Bootstrap button style. Any descendent component in the component hierarchy can use the `ButtonClass` property through the `ThemeInfo` cascading value.
`Shared/MainLayout.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Shared/MainLayout.razor":::
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Shared/MainLayout.razor" highlight="2,9-13,17":::
## `[CascadingParameter]` attribute
@@ -733,37 +759,7 @@ The following component binds the `ThemeInfo` cascading value to a cascading par
`Pages/ThemedCounter.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/ThemedCounter.razor":::
-
-Similar to a regular component parameter, components accepting a cascading parameter are rerendered when the cascading value is changed. For instance, configuring a different theme instance causes the `ThemedCounter` component from the [`CascadingValue` component](#cascadingvalue-component) section to rerender:
-
-`Shared/MainLayout.razor`:
-
-```razor
-
-
-
-
-
- @Body
-
-
- Dark mode
-
-
-@code {
- private ThemeInfo theme = new() { ButtonClass = "btn-success" };
-
- private void ChangeToDarkTheme()
- {
- theme = new() { ButtonClass = "btn-darkmode-success" };
- }
-}
-```
-
- can be used to indicate that a cascading parameter doesn't change after initialization.
+:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/ThemedCounter.razor" highlight="2,15-17,23-24":::
## Cascade multiple values
@@ -779,22 +775,26 @@ In the following example, two [`CascadingValue`](xref:Microsoft.AspNetCore.Compo
@code {
- private CascadingType? parentCascadeParameter1;
+ private CascadingType parentCascadeParameter1;
[Parameter]
- public CascadingType? ParentCascadeParameter2 { get; set; }
+ public CascadingType ParentCascadeParameter2 { get; set; }
+
+ ...
}
```
In a descendant component, the cascaded parameters receive their cascaded values from the ancestor component by :
```razor
+...
+
@code {
[CascadingParameter(Name = "CascadeParam1")]
- protected CascadingType? ChildCascadeParameter1 { get; set; }
-
+ protected CascadingType ChildCascadeParameter1 { get; set; }
+
[CascadingParameter(Name = "CascadeParam2")]
- protected CascadingType? ChildCascadeParameter2 { get; set; }
+ protected CascadingType ChildCascadeParameter2 { get; set; }
}
```
@@ -849,13 +849,13 @@ Child `Tab` components aren't explicitly passed as parameters to the `TabSet`. I
@code {
[Parameter]
- public RenderFragment? ChildContent { get; set; }
+ public RenderFragment ChildContent { get; set; }
- public ITab? ActiveTab { get; private set; }
+ public ITab ActiveTab { get; private set; }
public void AddTab(ITab tab)
{
- if (ActiveTab is null)
+ if (ActiveTab == null)
{
SetActiveTab(tab);
}
@@ -888,25 +888,25 @@ Descendent `Tab` components capture the containing `TabSet` as a cascading param
@code {
[CascadingParameter]
- public TabSet? ContainerTabSet { get; set; }
+ public TabSet ContainerTabSet { get; set; }
[Parameter]
- public string? Title { get; set; }
+ public string Title { get; set; }
[Parameter]
- public RenderFragment? ChildContent { get; set; }
+ public RenderFragment ChildContent { get; set; }
- private string? TitleCssClass =>
- ContainerTabSet?.ActiveTab == this ? "active" : null;
+ private string TitleCssClass =>
+ ContainerTabSet.ActiveTab == this ? "active" : null;
protected override void OnInitialized()
{
- ContainerTabSet?.AddTab(this);
+ ContainerTabSet.AddTab(this);
}
private void ActivateTab()
{
- ContainerTabSet?.SetActiveTab(this);
+ ContainerTabSet.SetActiveTab(this);
}
}
```
diff --git a/aspnetcore/blazor/components/class-libraries.md b/aspnetcore/blazor/components/class-libraries.md
index e8f0f9ffffa1..549e7740f39b 100644
--- a/aspnetcore/blazor/components/class-libraries.md
+++ b/aspnetcore/blazor/components/class-libraries.md
@@ -5,7 +5,7 @@ description: Discover how components can be included in Blazor apps from an exte
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/components/class-libraries
---
# Consume ASP.NET Core Razor components from a Razor class library (RCL)
diff --git a/aspnetcore/blazor/components/control-head-content.md b/aspnetcore/blazor/components/control-head-content.md
index a18d8661c616..512adb199f05 100644
--- a/aspnetcore/blazor/components/control-head-content.md
+++ b/aspnetcore/blazor/components/control-head-content.md
@@ -5,14 +5,14 @@ description: Learn how to control head content in Blazor apps, including how to
monikerRange: '>= aspnetcore-6.0'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/components/control-head-content
---
# Control `` content in ASP.NET Core Blazor apps
Razor components can modify the HTML `` element content of a page, including setting the page's title (`` element) and modifying metadata (`` elements).
-:::moniker range="< aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
## Control `` content in a Razor component
@@ -24,27 +24,7 @@ The following example sets the page's title and description using Razor.
`Pages/ControlHeadContent.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor" highlight="13,15-17":::
-
-## Control `` content during prerendering
-
-*This section applies to prerendered Blazor WebAssembly apps and Blazor Server apps.*
-
-When [Razor components are prerendered](xref:blazor/components/prerendering-and-integration), the use of a layout page (`_Layout.cshtml`) is required to control `` content with the and components. The reason for this requirement is that components that control `` content must be rendered before the layout with the component. **This order of rendering is required to control head content.**
-
-If the shared `_Layout.cshtml` file doesn't have a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component, add it to the `` elements.
-
-In a **required**, shared `_Layout.cshtml` file of a Blazor Server app or Razor Pages/MVC app that embeds components into pages or views:
-
-```cshtml
-
-```
-
-In a **required**, shared `_Layout.cshtml` file of a prerendered hosted Blazor WebAssembly app:
-
-```cshtml
-
-```
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor" highlight="13,15-17":::
## `HeadOutlet` component
@@ -58,7 +38,7 @@ builder.RootComponents.Add("head::after");
When the [`::after` pseudo-selector](https://developer.mozilla.org/docs/Web/CSS/::after) is specified, the contents of the root component are appended to the existing head contents instead of replacing the content. This allows the app to retain static head content in `wwwroot/index.html` without having to repeat the content in the app's Razor components.
-In Blazor Server apps created from the Blazor Server project template, a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) renders `` content for the component in `Pages/_Layout.cshtml`:
+In Blazor Server apps created from the Blazor Server project template, a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) renders `` content for the component in `Pages/_Host.cshtml`:
```cshtml
@@ -91,7 +71,7 @@ Mozilla MDN Web Docs documentation:
:::moniker-end
-:::moniker range=">= aspnetcore-7.0"
+:::moniker range="< aspnetcore-7.0"
## Control `` content in a Razor component
@@ -103,7 +83,27 @@ The following example sets the page's title and description using Razor.
`Pages/ControlHeadContent.razor`:
-:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor" highlight="13,15-17":::
+:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/control-head-content/ControlHeadContent.razor" highlight="13,15-17":::
+
+## Control `` content during prerendering
+
+*This section applies to prerendered Blazor WebAssembly apps and Blazor Server apps.*
+
+When [Razor components are prerendered](xref:blazor/components/prerendering-and-integration), the use of a layout page (`_Layout.cshtml`) is required to control `` content with the and components. The reason for this requirement is that components that control `` content must be rendered before the layout with the component. **This order of rendering is required to control head content.**
+
+If the shared `_Layout.cshtml` file doesn't have a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) for a component, add it to the `` elements.
+
+In a **required**, shared `_Layout.cshtml` file of a Blazor Server app or Razor Pages/MVC app that embeds components into pages or views:
+
+```cshtml
+
+```
+
+In a **required**, shared `_Layout.cshtml` file of a prerendered hosted Blazor WebAssembly app:
+
+```cshtml
+
+```
## `HeadOutlet` component
@@ -117,7 +117,7 @@ builder.RootComponents.Add("head::after");
When the [`::after` pseudo-selector](https://developer.mozilla.org/docs/Web/CSS/::after) is specified, the contents of the root component are appended to the existing head contents instead of replacing the content. This allows the app to retain static head content in `wwwroot/index.html` without having to repeat the content in the app's Razor components.
-In Blazor Server apps created from the Blazor Server project template, a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) renders `` content for the component in `Pages/_Host.cshtml`:
+In Blazor Server apps created from the Blazor Server project template, a [Component Tag Helper](xref:mvc/views/tag-helpers/builtin-th/component-tag-helper) renders `` content for the component in `Pages/_Layout.cshtml`:
```cshtml
@@ -148,5 +148,4 @@ Mozilla MDN Web Docs documentation:
* [``: The Document Title element](https://developer.mozilla.org/docs/Web/HTML/Element/title)
* [``: The metadata element](https://developer.mozilla.org/docs/Web/HTML/Element/meta)
-
:::moniker-end
diff --git a/aspnetcore/blazor/components/css-isolation.md b/aspnetcore/blazor/components/css-isolation.md
index 4df31c7ff1e9..368da218b4cc 100644
--- a/aspnetcore/blazor/components/css-isolation.md
+++ b/aspnetcore/blazor/components/css-isolation.md
@@ -5,7 +5,7 @@ description: Learn how CSS isolation scopes CSS to Razor components, which can s
monikerRange: '>= aspnetcore-5.0'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/components/css-isolation
---
# ASP.NET Core Blazor CSS isolation
diff --git a/aspnetcore/blazor/components/data-binding.md b/aspnetcore/blazor/components/data-binding.md
index e6becc6a9aad..a0162911faed 100644
--- a/aspnetcore/blazor/components/data-binding.md
+++ b/aspnetcore/blazor/components/data-binding.md
@@ -5,14 +5,14 @@ description: Learn about data binding features for Razor components and Document
monikerRange: '>= aspnetcore-3.1'
ms.author: riande
ms.custom: mvc
-ms.date: 11/09/2021
+ms.date: 11/08/2022
uid: blazor/components/data-binding
---
# ASP.NET Core Blazor data binding
This article explains data binding features for Razor components and Document Object Model (DOM) elements in Blazor apps.
-:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
+:::moniker range=">= aspnetcore-7.0"
Razor components provide data binding features with the [`@bind`](xref:mvc/views/razor#bind) Razor directive attribute with a field, property, or Razor expression value.
@@ -25,7 +25,7 @@ When an `` element loses focus, its bound field or property is updated.
`Pages/Bind.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/data-binding/Bind.razor" highlight="4,8":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/data-binding/Bind.razor" highlight="4,8":::
The text box is updated in the UI only when the component is rendered, not in response to changing the field's or property's value. Since components render themselves after event handler code executes, field and property updates are usually reflected in the UI immediately after an event handler is triggered.
@@ -33,7 +33,7 @@ As a demonstration of how data binding composes in HTML, the following example b
`Pages/BindTheory.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/data-binding/BindTheory.razor" highlight="12-14":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/data-binding/BindTheory.razor" highlight="12-14":::
When the `BindTheory` component is rendered, the `value` of the HTML demonstration `` element comes from the `InputValue` property. When the user enters a value in the text box and changes element focus, the `onchange` event is fired and the `InputValue` property is set to the changed value. In reality, code execution is more complex because [`@bind`](xref:mvc/views/razor#bind) handles cases where type conversions are performed. In general, [`@bind`](xref:mvc/views/razor#bind) associates the current value of an expression with a `value` attribute and handles changes using the registered handler.
@@ -41,12 +41,59 @@ Bind a property or field on other [Document Object Model (DOM)](https://develope
`Page/BindEvent.razor`:
-:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/data-binding/BindEvent.razor" highlight="4":::
+:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/data-binding/BindEvent.razor" highlight="4":::
+
+To execute asynchronous logic after binding, use `@bind:after="{EVENT}"` with a DOM event for the `{EVENT}` placeholder. An assigned C# method isn't executed until the bound value is assigned synchronously.
+
+In the following example:
+
+* The `` element's `value` is bound to the value of `searchText` synchronously.
+* After each keystroke (`onchange` event) in the field, the `PerformSearch` method executes asynchronously.
+* `PerformSearch` calls a service with an asynchronous method (`FetchAsync`) to return search results.
+
+```razor
+@inject ISearchService SearchService
+
+
+
+@code {
+ private string? searchText;
+ private string[]? searchResult;
+
+ private async Task PerformSearch()
+ {
+ searchResult = await SearchService.FetchAsync(searchText);
+ }
+}
+```
+
+Components support two-way data binding by defining a pair of parameters:
+
+* `@bind:get`: Specifies the value to bind.
+* `@bind:set`: Specifies a callback for when the value changes.
+
+The `@bind:get` and `@bind:set` modifiers are always used together.
+
+Example:
+
+```razor
+
+
+@code {
+ [Parameter]
+ public string? Value { get; set; }
+
+ [Parameter]
+ public EventCallback ValueChanged { get; set; }
+}
+```
+
+For another example use of `@bind:get` and `@bind:set`, see the [Bind across more than two components](#bind-across-more-than-two-components) section later in this article.
Razor attribute binding is case sensitive:
-* `@bind` and `@bind:event` are valid.
-* `@Bind`/`@Bind:Event` (capital letters `B` and `E`) or `@BIND`/`@BIND:EVENT` (all capital letters) **are invalid**.
+* `@bind`, `@bind:event`, and `@bind:after` are valid.
+* `@Bind`/`@bind:Event`/`@bind:aftEr` (capital letters) or `@BIND`/`@BIND:EVENT`/`@BIND:AFTER` (all capital letters) **are invalid**.
## Multiple option selection with `