Skip to content

Commit 24910eb

Browse files
github-actions[bot]timdeschryverwadepickettRick-Andersonmikekistler
authored
Merge to Live (#35193)
* Adds .NET 9 sample to mongo app (#35189) * copy-paste to 9.x * update code to .NET 9 * update references to code * update references to 8.x code * upate ms date * add missing snapshot * Update aspnetcore/tutorials/first-mongo-app.md --------- Co-authored-by: Wade Pickett <[email protected]> * SSE return types /2 (#35152) * SSE return types /2 * SSE return types /2 * SSE return types /2 * SSE return types /2 * SSE return types /2 * fixes * Update aspnetcore/fundamentals/minimal-apis/responses.md Co-authored-by: Mike Kistler <[email protected]> * Apply suggestions from code review Co-authored-by: Mike Kistler <[email protected]> * react to feedback * Update aspnetcore/web-api/action-return-types/samples/10/ControllerSSE/HearRate.cs Co-authored-by: Mike Kistler <[email protected]> * react to feedback --------- Co-authored-by: Mike Kistler <[email protected]> * Update complex-data-model.md Fixes #35191 * WN .NET 10 Prev 3: Validation Support Minimal API (#35188) * WN .NET 10 Prev 3: Validation Support Minimal API * Added include to What's New topic for .NET 10 Preview 3 * Update with correct links * Format link for attribute * Correct DataAnnotations link * Add review suggestions, remove future tense and lines * Minor edit * Remove line breaks * fixed line break * [Pre3] Boot config file name change (#35176) * [Pre3] Declaratively persist state (#35198) * Blazor Pre3 final updates for release (#35200) * Patch Blazor Pre3 API (#35201) --------- Co-authored-by: Tim Deschryver <[email protected]> Co-authored-by: Wade Pickett <[email protected]> Co-authored-by: Rick Anderson <[email protected]> Co-authored-by: Mike Kistler <[email protected]> Co-authored-by: Luke Latham <[email protected]>
1 parent d799110 commit 24910eb

40 files changed

+1186
-121
lines changed

Diff for: aspnetcore/blazor/call-web-api.md

+2
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,8 @@ To opt-out of response streaming globally, use either of the following approache
992992
993993
* Set the `DOTNET_WASM_ENABLE_STREAMING_RESPONSE` environment variable to `false` or `0`.
994994
995+
............. AND REMOVE THE NEXT LINE .............
996+
995997
-->
996998

997999
To opt-out of response streaming globally, set the `DOTNET_WASM_ENABLE_STREAMING_RESPONSE` environment variable to `false` or `0`.

Diff for: aspnetcore/blazor/components/integration-hosted-webassembly.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ else
515515
protected override async Task OnInitializedAsync()
516516
{
517517
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
518-
"fetchdata", out var restored))
518+
nameof(forecasts), out var restored))
519519
{
520520
forecasts = await WeatherForecastService.GetForecastAsync(
521521
DateOnly.FromDateTime(DateTime.Now));
@@ -531,7 +531,7 @@ else
531531
532532
private Task PersistData()
533533
{
534-
ApplicationState.PersistAsJson("fetchdata", forecasts);
534+
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
535535
536536
return Task.CompletedTask;
537537
}
@@ -1030,7 +1030,7 @@ else
10301030
protected override async Task OnInitializedAsync()
10311031
{
10321032
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
1033-
"fetchdata", out var restored))
1033+
nameof(forecasts), out var restored))
10341034
{
10351035
forecasts =
10361036
await WeatherForecastService.GetForecastAsync(DateTime.Now);
@@ -1046,7 +1046,7 @@ else
10461046
10471047
private Task PersistData()
10481048
{
1049-
ApplicationState.PersistAsJson("fetchdata", forecasts);
1049+
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
10501050
10511051
return Task.CompletedTask;
10521052
}

Diff for: aspnetcore/blazor/components/integration.md

+87-6
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,83 @@ In `Pages/_Host.cshtml` of Blazor apps that are `ServerPrerendered` in a Blazor
402402
</body>
403403
```
404404

405+
:::moniker-end
406+
407+
:::moniker range=">= aspnetcore-10.0"
408+
409+
<!-- UPDATE 10.0 - API cross-link -->
410+
411+
Decide what state to persist using the <xref:Microsoft.AspNetCore.Components.PersistentComponentState> service. The `[SupplyParameterFromPersistentComponentState]` attribute applied to a property registers a callback to persist the state during prerendering and loads it when the component renders interactively or the service is instantiated.
412+
413+
In the following example, the `{TYPE}` placeholder represents the type of data to persist (for example, `WeatherForecast[]`).
414+
415+
```razor
416+
@code {
417+
[SupplyParameterFromPersistentComponentState]
418+
public {TYPE} Data { get; set; }
419+
}
420+
```
421+
422+
In the following example, the `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
423+
424+
`WeatherForecastPreserveState.razor`:
425+
426+
```razor
427+
@page "/weather-forecast-preserve-state"
428+
@using BlazorSample.Shared
429+
@inject IWeatherForecastService WeatherForecastService
430+
431+
<PageTitle>Weather Forecast</PageTitle>
432+
433+
<h1>Weather forecast</h1>
434+
435+
<p>This component demonstrates fetching data from the server.</p>
436+
437+
@if (Forecasts == null)
438+
{
439+
<p><em>Loading...</em></p>
440+
}
441+
else
442+
{
443+
<table class="table">
444+
<thead>
445+
<tr>
446+
<th>Date</th>
447+
<th>Temp. (C)</th>
448+
<th>Temp. (F)</th>
449+
<th>Summary</th>
450+
</tr>
451+
</thead>
452+
<tbody>
453+
@foreach (var forecast in Forecasts)
454+
{
455+
<tr>
456+
<td>@forecast.Date.ToShortDateString()</td>
457+
<td>@forecast.TemperatureC</td>
458+
<td>@forecast.TemperatureF</td>
459+
<td>@forecast.Summary</td>
460+
</tr>
461+
}
462+
</tbody>
463+
</table>
464+
}
465+
466+
@code {
467+
[SupplyParameterFromPersistentComponentState]
468+
public WeatherForecast[]? Forecasts { get; set; }
469+
470+
protected override async Task OnInitializedAsync()
471+
{
472+
Forecasts ??= await WeatherForecastService.GetForecastAsync(
473+
DateOnly.FromDateTime(DateTime.Now));
474+
}
475+
}
476+
```
477+
478+
:::moniker-end
479+
480+
:::moniker range=">= aspnetcore-7.0 < aspnetcore-10.0"
481+
405482
Decide what state to persist using the <xref:Microsoft.AspNetCore.Components.PersistentComponentState> service. <xref:Microsoft.AspNetCore.Components.PersistentComponentState.RegisterOnPersisting%2A?displayProperty=nameWithType> registers a callback to persist the component state before the app is paused. The state is retrieved when the application resumes. Make the call at the end of initialization code in order to avoid a potential race condition during app shutdown.
406483

407484
In the following example:
@@ -449,7 +526,7 @@ In the following example:
449526
}
450527
```
451528

452-
The following example is an updated version of the `FetchData` component based on the Blazor project template. The `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
529+
In the following example, the `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
453530

454531
`Pages/WeatherForecastPreserveState.razor`:
455532

@@ -502,7 +579,7 @@ else
502579
protected override async Task OnInitializedAsync()
503580
{
504581
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
505-
"fetchdata", out var restored))
582+
nameof(forecasts), out var restored))
506583
{
507584
forecasts =
508585
await WeatherForecastService.GetForecastAsync(
@@ -519,7 +596,7 @@ else
519596
520597
private Task PersistData()
521598
{
522-
ApplicationState.PersistAsJson("fetchdata", forecasts);
599+
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
523600
524601
return Task.CompletedTask;
525602
}
@@ -531,6 +608,10 @@ else
531608
}
532609
```
533610

611+
:::moniker-end
612+
613+
:::moniker range=">= aspnetcore-7.0"
614+
534615
By initializing components with the same state used during prerendering, any expensive initialization steps are only executed once. The rendered UI also matches the prerendered UI, so no flicker occurs in the browser.
535616

536617
The persisted prerendered state is transferred to the client, where it's used to restore the component state. [ASP.NET Core Data Protection](xref:security/data-protection/introduction) ensures that the data is transferred securely in Blazor Server apps.
@@ -969,7 +1050,7 @@ To solve these problems, Blazor supports persisting state in a prerendered page
9691050

9701051
Decide what state to persist using the <xref:Microsoft.AspNetCore.Components.PersistentComponentState> service. <xref:Microsoft.AspNetCore.Components.PersistentComponentState.RegisterOnPersisting%2A?displayProperty=nameWithType> registers a callback to persist the component state before the app is paused. The state is retrieved when the application resumes. Make the call at the end of initialization code in order to avoid a potential race condition during app shutdown.
9711052

972-
The following example is an updated version of the `FetchData` component based on the Blazor project template. The `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
1053+
In the following example, the `WeatherForecastPreserveState` component persists weather forecast state during prerendering and then retrieves the state to initialize the component. The [Persist Component State Tag Helper](xref:mvc/views/tag-helpers/builtin-th/persist-component-state-tag-helper) persists the component state after all component invocations.
9731054

9741055
`Pages/WeatherForecastPreserveState.razor`:
9751056

@@ -1022,7 +1103,7 @@ else
10221103
protected override async Task OnInitializedAsync()
10231104
{
10241105
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
1025-
"fetchdata", out var restored))
1106+
nameof(forecasts), out var restored))
10261107
{
10271108
forecasts =
10281109
await WeatherForecastService.GetForecastAsync(DateTime.Now);
@@ -1038,7 +1119,7 @@ else
10381119
10391120
private Task PersistData()
10401121
{
1041-
ApplicationState.PersistAsJson("fetchdata", forecasts);
1122+
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
10421123
10431124
return Task.CompletedTask;
10441125
}

Diff for: aspnetcore/blazor/components/lifecycle.md

+45-3
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ Prerendering waits for *quiescence*, which means that a component doesn't render
594594
595595
Welcome to your new app.
596596
597-
<SlowComponent />
597+
<Slow />
598598
```
599599

600600
> [!NOTE]
@@ -616,6 +616,46 @@ When the `Home` component is prerendering, the `Slow` component is quickly rende
616616

617617
To address the double rendering of the loading message and the re-execution of service and database calls, persist prerendered state with <xref:Microsoft.AspNetCore.Components.PersistentComponentState> for final rendering of the component, as seen in the following updates to the `Slow` component:
618618

619+
:::moniker-end
620+
621+
:::moniker range=">= aspnetcore-10.0"
622+
623+
```razor
624+
@page "/slow"
625+
@attribute [StreamRendering]
626+
627+
<h2>Slow Component</h2>
628+
629+
@if (Data is null)
630+
{
631+
<div><em>Loading...</em></div>
632+
}
633+
else
634+
{
635+
<div>@Data</div>
636+
}
637+
638+
@code {
639+
[SupplyParameterFromPersistentComponentState]
640+
public string? Data { get; set; }
641+
642+
protected override async Task OnInitializedAsync()
643+
{
644+
Data ??= await LoadDataAsync();
645+
}
646+
647+
private async Task<string> LoadDataAsync()
648+
{
649+
await Task.Delay(10000);
650+
return "Finished!";
651+
}
652+
}
653+
```
654+
655+
:::moniker-end
656+
657+
:::moniker range=">= aspnetcore-8.0 < aspnetcore-10.0"
658+
619659
```razor
620660
@page "/slow"
621661
@attribute [StreamRendering]
@@ -639,7 +679,7 @@ else
639679
640680
protected override async Task OnInitializedAsync()
641681
{
642-
if (!ApplicationState.TryTakeFromJson<string>("data", out var restored))
682+
if (!ApplicationState.TryTakeFromJson<string>(nameof(data), out var restored))
643683
{
644684
data = await LoadDataAsync();
645685
}
@@ -654,7 +694,7 @@ else
654694
655695
private Task PersistData()
656696
{
657-
ApplicationState.PersistAsJson("data", data);
697+
ApplicationState.PersistAsJson(nameof(data), data);
658698
659699
return Task.CompletedTask;
660700
}
@@ -672,6 +712,8 @@ else
672712
}
673713
```
674714

715+
:::moniker-end
716+
675717
By combining streaming rendering with persistent component state:
676718

677719
* Services and databases only require a single call for component initialization.

0 commit comments

Comments
 (0)