Skip to content

Commit fba6a36

Browse files
authored
Merge pull request #35320 from dotnet/main
2 parents 94f6ec3 + 781c7b1 commit fba6a36

File tree

76 files changed

+512
-112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+512
-112
lines changed

aspnetcore/blazor/call-web-api.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,25 @@ The [`System.Net.Http.Json`](https://www.nuget.org/packages/System.Net.Http.Json
2222

2323
## Use a token handler for web API calls
2424

25-
Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the next section.
25+
Blazor Web Apps with OIDC authentication can use a token handler approach to make outgoing requests to secure external web API calls. This approach is used by the `BlazorWebAppOidc` and `BlazorWebAppOidcServer` sample apps described in the *Sample apps* section of this article.
2626

2727
For more information, see the following resources:
2828

2929
* <xref:blazor/security/additional-scenarios#use-a-token-handler-for-web-api-calls>
3030
* *Secure an ASP.NET Core Blazor Web App with OpenID Connect (OIDC)*
31-
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern)
32-
* [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?view=aspnetcore-9.0&pivots=non-bff-pattern-server)
31+
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern)
32+
* [Non-BFF pattern (Interactive Server)](xref:blazor/security/blazor-web-app-oidc?pivots=non-bff-pattern-server)
33+
34+
## Microsoft identity platform for web API calls
35+
36+
Blazor Web Apps that use use [Microsoft identity platform](/entra/identity-platform/)/[Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra) can make streamlined calls using Entra-specific API. This approach is used by the `BlazorWebAppEntra` and `BlazorWebAppEntraBff` sample apps described in the *Sample apps* section of this article.
37+
38+
For more information, see the following resources:
39+
40+
* <xref:blazor/security/additional-scenarios#use-a-token-handler-for-web-api-calls>
41+
* *Secure an ASP.NET Core Blazor Web App with Microsoft Entra ID*
42+
* [Non-BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern)
43+
* [BFF pattern (Interactive Auto)](xref:blazor/security/blazor-web-app-entra?pivots=non-bff-pattern-server)
3344

3445
## Sample apps
3546

aspnetcore/blazor/components/built-in-components.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
3737
* [`InputSelect`](xref:blazor/forms/input-components)
3838
* [`InputText`](xref:blazor/forms/input-components)
3939
* [`InputTextArea`](xref:blazor/forms/input-components)
40-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
40+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
4141
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
4242
* [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes)
4343
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
@@ -77,7 +77,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
7777
* [`InputSelect`](xref:blazor/forms/input-components)
7878
* [`InputText`](xref:blazor/forms/input-components)
7979
* [`InputTextArea`](xref:blazor/forms/input-components)
80-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
80+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
8181
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
8282
* [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes)
8383
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
@@ -115,7 +115,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
115115
* [`InputSelect`](xref:blazor/forms/input-components)
116116
* [`InputText`](xref:blazor/forms/input-components)
117117
* [`InputTextArea`](xref:blazor/forms/input-components)
118-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
118+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
119119
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
120120
* [`NavigationLock`](xref:blazor/fundamentals/routing#handleprevent-location-changes)
121121
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
@@ -149,7 +149,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
149149
* [`InputSelect`](xref:blazor/forms/input-components)
150150
* [`InputText`](xref:blazor/forms/input-components)
151151
* [`InputTextArea`](xref:blazor/forms/input-components)
152-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
152+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
153153
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
154154
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
155155
* [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope)
@@ -177,7 +177,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
177177
* [`InputSelect`](xref:blazor/forms/input-components)
178178
* [`InputText`](xref:blazor/forms/input-components)
179179
* [`InputTextArea`](xref:blazor/forms/input-components)
180-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
180+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
181181
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
182182
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
183183
* [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope)
@@ -203,7 +203,7 @@ The following built-in Razor components are provided by the Blazor framework. Fo
203203
* [`InputSelect`](xref:blazor/forms/input-components)
204204
* [`InputText`](xref:blazor/forms/input-components)
205205
* [`InputTextArea`](xref:blazor/forms/input-components)
206-
* [`LayoutComponentBase`](xref:blazor/components/layouts#layout-components)
206+
* [`LayoutComponentBase`](xref:blazor/components/layouts#create-a-layout-component)
207207
* [`LayoutView`](xref:blazor/components/layouts#apply-a-layout-to-arbitrary-content-layoutview-component)
208208
* [`NavLink`](xref:blazor/fundamentals/routing#navlink-component)
209209
* [`OwningComponentBase`](xref:fundamentals/dependency-injection#utility-base-component-classes-to-manage-a-di-scope)

aspnetcore/blazor/components/event-handling.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ For event handling:
4040

4141
:::moniker-end
4242

43+
> [!IMPORTANT]
44+
> The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, the entire process fails when an exception isn't caught if `void` is returned. Always return a <xref:System.Threading.Tasks.Task>/<xref:System.Threading.Tasks.ValueTask> from asynchronous methods.
45+
4346
The following code:
4447

4548
* Calls the `UpdateHeading` method when the button is selected in the UI.

aspnetcore/blazor/components/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ Razor syntax for C# control structures, directives, and directive attributes are
638638

639639
### Asynchronous methods (`async`) don't support returning `void`
640640

641-
The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, exceptions aren't caught if `void` is returned. Always return a <xref:System.Threading.Tasks.Task> from asynchronous methods.
641+
The Blazor framework doesn't track `void`-returning asynchronous methods (`async`). As a result, the entire process fails when an exception isn't caught if `void` is returned. Always return a <xref:System.Threading.Tasks.Task>/<xref:System.Threading.Tasks.ValueTask> from asynchronous methods.
642642

643643
### Nested components
644644

aspnetcore/blazor/components/layouts.md

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ Some app elements, such as menus, copyright messages, and company logos, are usu
2020

2121
A Blazor layout is a Razor component that shares markup with components that reference it. Layouts can use [data binding](xref:blazor/components/data-binding), [dependency injection](xref:blazor/fundamentals/dependency-injection), and other features of components.
2222

23-
## Layout components
24-
25-
### Create a layout component
23+
## Create a layout component
2624

2725
To create a layout component:
2826

@@ -73,7 +71,7 @@ The following `DoctorWhoLayout` component shows the Razor template of a layout c
7371

7472
:::moniker-end
7573

76-
### `MainLayout` component
74+
## `MainLayout` component
7775

7876
In an app created from a [Blazor project template](xref:blazor/project-structure), the `MainLayout` component is the app's [default layout](#apply-a-default-layout-to-an-app). Blazor's layout adopts the [:::no-loc text="Flexbox"::: layout model](https://developer.mozilla.org/docs/Glossary/Flexbox) ([W3C specification](https://www.w3.org/TR/css-flexbox-1/)).
7977

@@ -94,6 +92,86 @@ In an app created from a [Blazor project template](xref:blazor/project-structure
9492

9593
:::moniker-end
9694

95+
:::moniker range=">= aspnetcore-8.0"
96+
97+
<!-- UPDATE 11.0 Is https://github.com/dotnet/aspnetcore/issues/52768 addressed
98+
to resolve the following limitation? -->
99+
100+
## Statically-rendered layout components
101+
102+
When a Blazor Web App adopts per-page/component rendering (the `Routes` component doesn't specify an interactive render mode), layout components are rendered statically on the server. Applying an interactive render mode directly to a layout isn't supported because Blazor doesn't support serializing a <xref:Microsoft.AspNetCore.Components.RenderFragment> (`@Body` in this case) as a root component parameter. For example, placing `@rendermode InteractiveServer` at the top of the `MainLayout` component results in the following runtime exception:
103+
104+
> :::no-loc text="System.InvalidOperationException: Cannot pass the parameter 'Body' to component 'MainLayout' with rendermode 'InteractiveServerRenderMode'. This is because the parameter is of the delegate type 'Microsoft.AspNetCore.Components.RenderFragment', which is arbitrary code and cannot be serialized.":::
105+
106+
This applies to any layout component that inherits from <xref:Microsoft.AspNetCore.Components.LayoutComponentBase> in an app that adopts per-page/component rendering.
107+
108+
This scenario might be addressed in a future release of Blazor. For more information, see [[Blazor] Support serializing render fragments from SSR (`dotnet/aspnetcore` #52768)](https://github.com/dotnet/aspnetcore/issues/52768). In the meantime, you can adopt the following approach in a Blazor Web App that adopts per-page/component rendering.
109+
110+
Create a wrapper component that's capable of interactivity. In the following example, a wrapper component contains a [Blazor section](xref:blazor/components/sections) that can receive content from a child component.
111+
112+
In the `_Imports.razor` file, add an [`@using`](xref:mvc/views/razor#using) directive for sections (<xref:Microsoft.AspNetCore.Components.Sections?displayProperty=fullName>):
113+
114+
```razor
115+
@using Microsoft.AspNetCore.Components.Sections
116+
```
117+
118+
Create the following interactive wrapper component in the `Pages` folder.
119+
120+
`Pages/InteractiveWrapper.razor`:
121+
122+
```razor
123+
@rendermode InteractiveServer
124+
125+
<div>
126+
<SectionOutlet SectionName="top-bar" />
127+
</div>
128+
129+
@ChildContent
130+
131+
@code {
132+
[Parameter]
133+
public RenderFragment? ChildContent { get; set; }
134+
}
135+
```
136+
137+
The `Counter` component can use the wrapper component and set interactive section content. In the following example, a counter button is placed in the section.
138+
139+
`Pages/Counter.razor`:
140+
141+
```razor
142+
@page "/counter"
143+
@rendermode InteractiveServer
144+
145+
<InteractiveWrapper>
146+
147+
<SectionContent SectionName="top-bar">
148+
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
149+
</SectionContent>
150+
151+
<PageTitle>Counter</PageTitle>
152+
153+
<h1>Counter</h1>
154+
155+
<p role="status">Current count: @currentCount</p>
156+
157+
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
158+
159+
</InteractiveWrapper>
160+
161+
@code {
162+
private int currentCount = 0;
163+
164+
private void IncrementCount()
165+
{
166+
currentCount++;
167+
}
168+
}
169+
```
170+
171+
Other components around the app can also wrap content in the `InteractiveWrapper` component and set interactive section content.
172+
173+
:::moniker-end
174+
97175
## Apply a layout
98176

99177
### Make the layout namespace available
@@ -220,7 +298,7 @@ Specify the default app layout in the <xref:Microsoft.AspNetCore.Components.Rout
220298
<RouteView RouteData="routeData" DefaultLayout="typeof({LAYOUT})" />
221299
```
222300

223-
In the preceding example, the `{LAYOUT}` placeholder is the layout (for example, `DoctorWhoLayout` if the layout file name is `DoctorWhoLayout.razor`). You may need to idenfity the layout's namespace depending on the .NET version and type of Blazor app. For more information, see the [Make the layout namespace available](#make-the-layout-namespace-available) section.
301+
In the preceding example, the `{LAYOUT}` placeholder is the layout (for example, `DoctorWhoLayout` if the layout file name is `DoctorWhoLayout.razor`). You may need to identify the layout's namespace depending on the .NET version and type of Blazor app. For more information, see the [Make the layout namespace available](#make-the-layout-namespace-available) section.
224302

225303
Specifying the layout as a default layout in the <xref:Microsoft.AspNetCore.Components.Routing.Router> component's <xref:Microsoft.AspNetCore.Components.RouteView> is a useful practice because you can override the layout on a per-component or per-folder basis, as described in the preceding sections of this article. We recommend using the <xref:Microsoft.AspNetCore.Components.Routing.Router> component to set the app's default layout because it's the most general and flexible approach for using layouts.
226304

aspnetcore/blazor/components/render-modes.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,11 @@ Non-serializable component parameters, such as child content or a render fragmen
576576

577577
> :::no-loc text="System.InvalidOperationException: Cannot pass the parameter 'ChildContent' to component 'SharedMessage' with rendermode 'InteractiveServerRenderMode'. This is because the parameter is of the delegate type 'Microsoft.AspNetCore.Components.RenderFragment', which is arbitrary code and cannot be serialized.":::
578578
579+
<!-- UPDATE 11.0 Is https://github.com/dotnet/aspnetcore/issues/52768 addressed
580+
to resolve the following limitation? -->
581+
582+
The same thing happens if you attempt to adopt interactive rendering in a layout that inherits from <xref:Microsoft.AspNetCore.Components.LayoutComponentBase>, such as the app's `MainLayout` component, in an app that adopts per-page/component rendering. For more information, see <xref:blazor/components/layouts#statically-rendered-layout-components>.
583+
579584
To circumvent the preceding limitation, wrap the child component in another component that doesn't have the parameter. This is the approach taken in the Blazor Web App project template with the `Routes` component (`Components/Routes.razor`) to wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component.
580585

581586
`WrapperComponent.razor`:

aspnetcore/blazor/components/sections.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,4 @@ A section interacts with other Blazor features in the following ways:
9292
* [Cascading values](xref:blazor/components/cascading-values-and-parameters) flow into section content from where the content is defined by the <xref:Microsoft.AspNetCore.Components.Sections.SectionContent> component.
9393
* Unhandled exceptions are handled by [error boundaries](xref:blazor/fundamentals/handle-errors#error-boundaries) defined around a <xref:Microsoft.AspNetCore.Components.Sections.SectionContent> component.
9494
* A Razor component configured for [streaming rendering](xref:blazor/components/rendering#streaming-rendering) also configures section content provided by a <xref:Microsoft.AspNetCore.Components.Sections.SectionContent> component to use streaming rendering.
95+
* A section that contains interactive components is statically rendered (non-functional) in a layout component in a Blazor Web App that adopts per-page/component rendering. For more information, see <xref:blazor/components/layouts#statically-rendered-layout-components>.

aspnetcore/blazor/host-and-deploy/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ To host a Blazor app in IIS, see the following resources:
6868
* IIS hosting
6969
* <xref:tutorials/publish-to-iis>
7070
* <xref:host-and-deploy/iis/index>
71-
* <xref:blazor/host-and-deploy/server/index>: Server apps running on IIS, including IIS with Azure Virtual Machines (VMs) running Windows OS and Azure App Service.
72-
* <xref:blazor/host-and-deploy/webassembly/index>: Includes additional guidance for Blazor WebAssembly apps hosted on IIS, including static site hosting, custom `web.config` files, URL rewriting, sub-apps, compression, and Azure Storage static file hosting.
71+
* <xref:blazor/host-and-deploy/server/index>: Blazor Web Apps (.NET 8 or later) and Blazor Server apps (.NET 7 or earlier) running on IIS, including IIS with Azure Virtual Machines (VMs) running Windows OS and Azure App Service.
72+
* <xref:blazor/host-and-deploy/webassembly/iis>: Standalone Blazor WebAssembly apps (all .NET releases) and hosted Blazor WebAssembly apps (.NET 7 or earlier).
7373
* IIS sub-application hosting
7474
* Follow the [app base path guidance](xref:blazor/host-and-deploy/app-base-path) prior to publishing the app. The examples use an app base path of `/CoolApp` and show how to [obtain the base path from app settings or other configuration providers](xref:blazor/host-and-deploy/app-base-path#obtain-the-app-base-path-from-configuration).
7575
* Follow the sub-application configuration guidance in <xref:host-and-deploy/iis/advanced#sub-applications>. The sub-app's folder path under the root site becomes the virtual path of the sub-app. For an app base path of `/CoolApp`, the Blazor app is placed in a folder named `CoolApp` under the root site and the sub-app takes on a virtual path of `/CoolApp`.

aspnetcore/blazor/host-and-deploy/webassembly/azure-static-web-apps.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
2-
title: Host and deploy ASP.NET Core Blazor WebAssembly with Azure Static Web Apps
2+
title: Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Static Web Apps
33
author: guardrex
4-
description: Learn how to host and deploy Blazor WebAssembly with Microsoft Azure Static Web Apps.
4+
description: Learn how to host and deploy standalone Blazor WebAssembly with Microsoft Azure Static Web Apps.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
88
ms.date: 03/31/2025
99
uid: blazor/host-and-deploy/webassembly/azure-static-web-apps
1010
---
11-
# Host and deploy ASP.NET Core Blazor WebAssembly with Azure Static Web Apps
11+
# Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Static Web Apps
1212

1313
[!INCLUDE[](~/includes/not-latest-version.md)]
1414

15-
This article explains how to host and deploy Blazor WebAssembly with [Microsoft Azure Static Web Apps](https://azure.microsoft.com/products/app-service/static).
15+
This article explains how to host and deploy standalone Blazor WebAssembly with [Microsoft Azure Static Web Apps](https://azure.microsoft.com/products/app-service/static).
1616

1717
## Deploy from Visual Studio
1818

aspnetcore/blazor/host-and-deploy/webassembly/azure-storage.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
---
2-
title: Host and deploy ASP.NET Core Blazor WebAssembly with Azure Storage
2+
title: Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Storage
33
author: guardrex
4-
description: Learn how to host and deploy Blazor WebAssembly using Microsoft Azure Storage.
4+
description: Learn how to host and deploy standalone Blazor WebAssembly using Microsoft Azure Storage.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: riande
77
ms.custom: mvc
88
ms.date: 03/31/2025
99
uid: blazor/host-and-deploy/webassembly/azure-storage
1010
---
11-
# Host and deploy ASP.NET Core Blazor WebAssembly with Azure Storage
11+
# Host and deploy ASP.NET Core standalone Blazor WebAssembly with Azure Storage
1212

1313
[!INCLUDE[](~/includes/not-latest-version.md)]
1414

15-
This article explains how to host and deploy Blazor WebAssembly using [Microsoft Azure Storage](/azure/storage/common/storage-introduction).
15+
This article explains how to host and deploy standalone Blazor WebAssembly using [Microsoft Azure Storage](/azure/storage/common/storage-introduction).
1616

1717
Azure Storage static file hosting allows serverless Blazor app hosting. Custom domain names, the Azure Content Delivery Network (CDN), and HTTPS are supported.
1818

0 commit comments

Comments
 (0)