Skip to content

Commit afaf210

Browse files
authored
Merge pull request #35548 from dotnet/main
2 parents 0eaae08 + 23f8f60 commit afaf210

File tree

19 files changed

+448
-61
lines changed

19 files changed

+448
-61
lines changed

aspnetcore/blazor/call-web-api.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn how to call a web API from Blazor apps.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: wpickett
77
ms.custom: mvc
8-
ms.date: 04/29/2025
8+
ms.date: 05/30/2025
99
uid: blazor/call-web-api
1010
---
1111
# Call a web API from ASP.NET Core Blazor
@@ -33,7 +33,7 @@ For more information, see the following resources:
3333

3434
## Microsoft identity platform for web API calls
3535

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 web API calls with API provided by the [`Microsoft.Identity.Web.DownstreamApi` NuGet package](https://www.nuget.org/packages/Microsoft.Identity.Web.DownstreamApi).
36+
Blazor Web Apps that use use [Microsoft identity platform](/entra/identity-platform/) with [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 web API calls with API provided by the [`Microsoft.Identity.Web.DownstreamApi` NuGet package](https://www.nuget.org/packages/Microsoft.Identity.Web.DownstreamApi).
3737

3838
[!INCLUDE[](~/includes/package-reference.md)]
3939

@@ -291,13 +291,13 @@ The solution includes a demonstration of obtaining weather data securely via an
291291
292292
### `BlazorWebAppEntra`
293293
294-
A Blazor Web App with global Auto interactivity that uses [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). The solution includes a demonstration of obtaining weather data securely via an external web API when a component that adopts Interactive Auto rendering is rendered on the client.
294+
A Blazor Web App with global Auto interactivity that uses [Microsoft identity platform](/entra/identity-platform/) with [Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra). The solution includes a demonstration of obtaining weather data securely via an external web API when a component that adopts Interactive Auto rendering is rendered on the client.
295295
296296
### `BlazorWebAppEntraBff`
297297
298298
A Blazor Web App with global Auto interactivity that uses:
299299
300-
* [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).
300+
* [Microsoft identity platform](/entra/identity-platform/) with [Microsoft Identity Web packages](/entra/msal/dotnet/microsoft-identity-web/) for [Microsoft Entra ID](https://www.microsoft.com/security/business/microsoft-entra).
301301
* The [Backend for Frontend (BFF) pattern](/azure/architecture/patterns/backends-for-frontends), which is a pattern of app development that creates backend services for frontend apps or interfaces.
302302
303303
The solution includes a demonstration of obtaining weather data securely via an external web API when a component that adopts Interactive Auto rendering is rendered on the client.
@@ -1095,6 +1095,9 @@ public class CookieHandler : DelegatingHandler
10951095
}
10961096
```
10971097
1098+
> [!NOTE]
1099+
> For guidance on how to access an `AuthenticationStateProvider` from a `DelegatingHandler`, see <xref:blazor/security/additional-scenarios#access-authenticationstateprovider-in-outgoing-request-middleware>.
1100+
10981101
The `CookieHandler` is registered in the `Program` file:
10991102
11001103
```csharp
@@ -1117,10 +1120,10 @@ For a demonstration, see <xref:blazor/security/webassembly/standalone-with-ident
11171120
When composing an <xref:System.Net.Http.HttpRequestMessage>, set the browser request credentials and header directly:
11181121
11191122
```csharp
1120-
var requestMessage = new HttpRequestMessage() { ... };
1123+
var request = new HttpRequestMessage() { ... };
11211124
1122-
requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
1123-
requestMessage.Headers.Add("X-Requested-With", [ "XMLHttpRequest" ]);
1125+
request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
1126+
request.Headers.Add("X-Requested-With", [ "XMLHttpRequest" ]);
11241127
```
11251128
11261129
## `HttpClient` and `HttpRequestMessage` with Fetch API request options
@@ -1153,7 +1156,7 @@ requestMessage.Headers.Add("X-Requested-With", [ "XMLHttpRequest" ]);
11531156
11541157
private async Task PostRequest()
11551158
{
1156-
var requestMessage = new HttpRequestMessage()
1159+
var request = new HttpRequestMessage()
11571160
{
11581161
Method = new HttpMethod("POST"),
11591162
RequestUri = new Uri("https://localhost:10000/todoitems"),
@@ -1169,13 +1172,13 @@ requestMessage.Headers.Add("X-Requested-With", [ "XMLHttpRequest" ]);
11691172
11701173
if (tokenResult.TryGetToken(out var token))
11711174
{
1172-
requestMessage.Headers.Authorization =
1175+
request.Headers.Authorization =
11731176
new AuthenticationHeaderValue("Bearer", token.Value);
11741177
1175-
requestMessage.Content.Headers.TryAddWithoutValidation(
1178+
request.Content.Headers.TryAddWithoutValidation(
11761179
"x-custom-header", "value");
11771180
1178-
var response = await Http.SendAsync(requestMessage);
1181+
var response = await Http.SendAsync(request);
11791182
var responseStatusCode = response.StatusCode;
11801183
11811184
responseBody = await response.Content.ReadAsStringAsync();
@@ -1219,10 +1222,10 @@ To opt-out of response streaming globally, use either of the following approache
12191222
12201223
To opt-out of response streaming globally, set the `DOTNET_WASM_ENABLE_STREAMING_RESPONSE` environment variable to `false` or `0`.
12211224
1222-
To opt-out of response streaming for an individual request, set <xref:Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserResponseStreamingEnabled%2A> to `false` on the <xref:System.Net.Http.HttpRequestMessage> (`requestMessage` in the following example):
1225+
To opt-out of response streaming for an individual request, set <xref:Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserResponseStreamingEnabled%2A> to `false` on the <xref:System.Net.Http.HttpRequestMessage> (`request` in the following example):
12231226
12241227
```csharp
1225-
requestMessage.SetBrowserResponseStreamingEnabled(false);
1228+
request.SetBrowserResponseStreamingEnabled(false);
12261229
```
12271230
12281231
:::moniker-end
@@ -1232,22 +1235,22 @@ requestMessage.SetBrowserResponseStreamingEnabled(false);
12321235
The HTTP response is typically buffered to enable support for synchronous reads on the response content. To enable support for response streaming, set <xref:Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserResponseStreamingEnabled%2A> to `true` on the <xref:System.Net.Http.HttpRequestMessage>:
12331236
12341237
```csharp
1235-
requestMessage.SetBrowserResponseStreamingEnabled(true);
1238+
request.SetBrowserResponseStreamingEnabled(true);
12361239
```
12371240
12381241
By default, [`HttpCompletionOption.ResponseContentRead`](xref:System.Net.Http.HttpCompletionOption) is set, which results in the <xref:System.Net.Http.HttpClient> completing after reading the entire response, including the content. In order to be able to use the <xref:Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserResponseStreamingEnabled%2A> option on large files, set [`HttpCompletionOption.ResponseHeadersRead`](xref:System.Net.Http.HttpCompletionOption) to avoid caching the file's content in memory:
12391242
12401243
```diff
1241-
- var response = await Http.SendAsync(requestMessage);
1242-
+ var response = await Http.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
1244+
- var response = await Http.SendAsync(request);
1245+
+ var response = await Http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
12431246
```
12441247
12451248
:::moniker-end
12461249
12471250
To include credentials in a cross-origin request, use the <xref:Microsoft.AspNetCore.Components.WebAssembly.Http.WebAssemblyHttpRequestMessageExtensions.SetBrowserRequestCredentials%2A> extension method:
12481251
12491252
```csharp
1250-
requestMessage.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
1253+
request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include);
12511254
```
12521255
12531256
For more information on Fetch API options, see [MDN web docs: WindowOrWorkerGlobalScope.fetch(): Parameters](https://developer.mozilla.org/docs/Web/API/fetch#Parameters).

aspnetcore/blazor/components/httpcontext.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ For additional context in *advanced* edge cases&dagger;, see the discussion in t
3232

3333
&dagger;Most developers building and maintaining Blazor apps don't need to delve into advanced concepts when the general guidance in this article is followed. The most important concept to keep in mind is that <xref:Microsoft.AspNetCore.Http.HttpContext> is fundamentally a server-based, request-response feature that's only generally available on the server during static SSR and only created when a user's circuit is established.
3434

35+
## Don't set or modify headers after the response starts
36+
37+
Attempting to set or modify a header after the first rendering (after the response starts) results in an error:
38+
39+
> :::no-loc text="System.InvalidOperationException: 'Headers are read-only, response has already started.'":::
40+
41+
Examples of situations that result in this error include:
42+
43+
* Calling <xref:Microsoft.AspNetCore.Identity.SignInManager%601.PasswordSignInAsync%2A?displayProperty=nameWithType>, which must set headers for Identity to function correctly, while adopting [streaming rendering](xref:blazor/components/rendering#streaming-rendering).
44+
* Attempting to set or modify a header after the response has started during interactive rendering.
45+
46+
For guidance on setting headers before the response starts, see <xref:blazor/fundamentals/startup#control-headers-in-c-code>.
47+
3548
:::moniker-end
3649

3750
:::moniker range="< aspnetcore-8.0"

aspnetcore/blazor/fundamentals/dependency-injection.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,12 @@ public static class CircuitServicesServiceCollectionExtensions
610610
}
611611
```
612612

613+
Call `AddCircuitServicesAccessor` in the app's `Program` file:
614+
615+
```csharp
616+
builder.Services.AddCircuitServicesAccessor();
617+
```
618+
613619
Access the circuit-scoped services by injecting the `CircuitServicesAccessor` where it's needed.
614620

615621
For an example that shows how to access the <xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider> from a <xref:System.Net.Http.DelegatingHandler> set up using <xref:System.Net.Http.IHttpClientFactory>, see <xref:blazor/security/additional-scenarios#access-authenticationstateprovider-in-outgoing-request-middleware>.

aspnetcore/blazor/fundamentals/startup.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ Control headers at startup in C# code using the following approaches.
525525

526526
In the following examples, a [Content Security Policy (CSP)](https://developer.mozilla.org/docs/Web/HTTP/Guides/CSP) is applied to the app via a CSP header. The `{POLICY STRING}` placeholder is the CSP policy string. For more information on CSPs, see <xref:blazor/security/content-security-policy>.
527527

528+
> [!NOTE]
529+
> Headers can't be set after the response starts. The approaches in this section only set headers before the response starts, so the approaches described here are safe. For more information, see <xref:blazor/components/httpcontext#dont-set-or-modify-headers-after-the-response-starts>.
530+
528531
### Server-side and prerendered client-side scenarios
529532

530533
Use [ASP.NET Core Middleware](xref:fundamentals/middleware/index) to control the headers collection.

0 commit comments

Comments
 (0)