10000 Support persistent component state across enhanced page navigations by Copilot · Pull Request #62526 · dotnet/aspnetcore · GitHub
[go: up one dir, main page]

Skip to content

Support persistent component state across enhanced page navigations #62526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address review feedback: Use PrerenderComponentApplicationStore, make…
… attribute implementations explicit, clear state after operations

Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com>
  • Loading branch information
Copilot and javiercn committed Jul 2, 2025
commit 2bc3d0e2eb323e9d8bb830d48e3c32c4671a1d8f
3 changes: 0 additions & 3 deletions src/Components/Web/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ Microsoft.AspNetCore.Components.Web.Internal.IInternalWebJSInProcessRuntime.Invo
virtual Microsoft.AspNetCore.Components.Routing.NavLink.ShouldMatch(string! uriAbsolute) -> bool
Microsoft.AspNetCore.Components.Web.RestoreStateOnPrerenderingAttribute
Microsoft.AspNetCore.Components.Web.RestoreStateOnPrerenderingAttribute.RestoreStateOnPrerenderingAttribute(bool restore = true) -> void
Microsoft.AspNetCore.Components.Web.RestoreStateOnPrerenderingAttribute.ShouldRestore(Microsoft.AspNetCore.Components.IPersistentComponentStateScenario! scenario) -> bool
Microsoft.AspNetCore.Components.Web.RestoreStateOnReconnectionAttribute
Microsoft.AspNetCore.Components.Web.RestoreStateOnReconnectionAttribute.RestoreStateOnReconnectionAttribute(bool restore = true) -> void
Microsoft.AspNetCore.Components.Web.RestoreStateOnReconnectionAttribute.ShouldRestore(Microsoft.AspNetCore.Components.IPersistentComponentStateScenario! scenario) -> bool
Microsoft.AspNetCore.Components.Web.UpdateStateOnEnhancedNavigationAttribute
Microsoft.AspNetCore.Components.Web.UpdateStateOnEnhancedNavigationAttribute.UpdateStateOnEnhancedNavigationAttribute() -> void
Microsoft.AspNetCore.Components.Web.UpdateStateOnEnhancedNavigationAttribute.ShouldRestore(Microsoft.AspNetCore.Components.IPersistentComponentStateScenario! scenario) -> bool
Microsoft.AspNetCore.Components.Web.WebPersistenceScenario
Microsoft.AspNetCore.Components.Web.WebPersistenceScenario.RenderMode.get -> Microsoft.AspNetCore.Components.IComponentRenderMode?
override Microsoft.AspNetCore.Components.Web.WebPersistenceScenario.Equals(object? obj) -> bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public RestoreStateOnPrerenderingAttribute(bool restore = true)
}

/// <inheritdoc />
public bool ShouldRestore(IPersistentComponentStateScenario scenario)
bool IPersistentStateFilter.ShouldRestore(IPersistentComponentStateScenario scenario)
{
return WebPersistenceFilter?.ShouldRestore(scenario) ?? false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public RestoreStateOnReconnectionAttribute(bool restore = true)
}

/// <inheritdoc />
public bool ShouldRestore(IPersistentComponentStateScenario scenario)
bool IPersistentStateFilter.ShouldRestore(IPersistentComponentStateScenario scenario)
{
return WebPersistenceFilter?.ShouldRestore(scenario) ?? false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public sealed class UpdateStateOnEnhancedNavigationAttribute : Attribute, IPersi
internal WebPersistenceFilter WebPersistenceFilter { get; } = WebPersistenceFilter.EnhancedNavigation;

/// <inheritdoc />
public bool ShouldRestore(IPersistentComponentStateScenario scenario)
bool IPersistentStateFilter.ShouldRestore(IPersistentComponentStateScenario scenario)
{
return WebPersistenceFilter.ShouldRestore(scenario);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ public void FilterAttributes_ShouldRestore_WorksCorrectly()
var reconnectionFilter = new RestoreStateOnReconnectionAttribute();

// Act & Assert
Assert.True(enhancedNavFilter.ShouldRestore(enhancedNavScenario));
Assert.False(enhancedNavFilter.ShouldRestore(prerenderingScenario));
Assert.False(enhancedNavFilter.ShouldRestore(reconnectionScenario));
Assert.True(((IPersistentStateFilter)enhancedNavFilter).ShouldRestore(enhancedNavScenario));
Assert.False(((IPersistentStateFilter)enhancedNavFilter).ShouldRestore(prerenderingScenario));
Assert.False(((IPersistentStateFilter)enhancedNavFilter).ShouldRestore(reconnectionScenario));

Assert.False(prerenderingFilter.ShouldRestore(enhancedNavScenario));
Assert.True(prerenderingFilter.ShouldRestore(prerenderingScenario));
Assert.False(prerenderingFilter.ShouldRestore(reconnectionScenario));
Assert.False(((IPersistentStateFilter)prerenderingFilter).ShouldRestore(enhancedNavScenario));
Assert.True(((IPersistentStateFilter)prerenderingFilter).ShouldRestore(prerenderingScenario));
Assert.False(((IPersistentStateFilter)prerenderingFilter).ShouldRestore(reconnectionScenario));

Assert.False(reconnectionFilter.ShouldRestore(enhancedNavScenario));
Assert.False(reconnectionFilter.ShouldRestore(prerenderingScenario));
Assert.True(reconnectionFilter.ShouldRestore(reconnectionScenario));
Assert.False(((IPersistentStateFilter)reconnectionFilter).ShouldRestore(enhancedNavScenario));
Assert.False(((IPersistentStateFilter)reconnectionFilter).ShouldRestore(prerenderingScenario));
Assert.True(((IPersistentStateFilter)reconnectionFilter).ShouldRestore(reconnectionScenario));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,18 @@ public WebAssemblyRenderer(IServiceProvider serviceProvider, ResourceAssetCollec
[UnconditionalSuppressMessage("Trimming", "IL2072", Justification = "These are root components which belong to the user and are in assemblies that don't get trimmed.")]
private async void OnUpdateRootComponents(RootComponentOperationBatch batch, IDictionary<string, byte[]>? persistentState)
{
PrerenderComponentApplicationStore? store = null;

// Handle persistent state restoration if available
if (_componentStatePersistenceManager != null && persistentState != null)
{
var store = new DictionaryPersistentComponentStateStore(persistentState);
store = new PrerenderComponentApplicationStore();
store.ExistingState.Clear();
foreach (var kvp in persistentState)
{
store.ExistingState[kvp.Key] = kvp.Value;
}

var scenario = _isFirstUpdate
? WebPersistenceScenario.Prerendering()
: WebPersistenceScenario.EnhancedNavigation(RenderMode.InteractiveWebAssembly);
Expand Down Expand Up @@ -97,6 +105,12 @@ private async void OnUpdateRootComponents(RootComponentOperationBatch batch, IDi
}
}

// Clear state after processing operations when it's not the first update
if (!_isFirstUpdate && store != null)
{
store.ExistingState.Clear();
}

NotifyEndUpdateRootComponents(batch.BatchId);
}

Expand Down
Loading
0