Skip to content

Conversation

@oroztocil
Copy link
Member

@oroztocil oroztocil commented Dec 11, 2025

Background

In .NET 10, resuming a Blazor circuit fails when the server has been restarted (and an out-of-process persistent storage is not used). Currently, this is handled on the client side by displaying a "reconnection failed" UI which requires the user to manually reload the page. Previously, in .NET 9 the page would reload automatically once the server has restarted.

Changes

  • Re-adds the default reloading behavior to:
    • the ReconnectModal component used in the Blazor project template
    • the DefaultReconnectDisplay implementation used in the framework as the fallback when no reconnection UI is found in the user code
  • Modifies the ComponentHub on the server to not send a client error when ResumeCircuit fails because of unavailable circuit state.
    • This error caused the "yellow bar" to appear in the application. The error could not be caught by the client-side reconnection logic as it was processed elsewhere by the hubs's handler (for the "JS.Error" message).
    • The PR changes ComponentHub.ResumeCircuit to only return a falsy result in the case of unavailable state (similarly to how ConnectCircuit indicates rejection), allowing the client-side reconnection logic to react to the rejection by the server properly.
  • Updates the behavior in DefaultReconnectionHandler.attemptPeriodicReconnection so that the display does not switch between "reconnect" and "pause" states.
    • This created a bad user experience because the information displayed in the reconnection modal would flicker between the two variants which can be confusing both visually and message-wise.
    • The PR change keeps the same logic for reconnection attempts (try to reconnect, then try to resume) but keeps the UI in the "reconnect" state.
    • Reasoning: The fact that automatic reconnection can now involve resuming circuit with state stored on the server is an internal technical detail of the overall workflow that should not be surfaced to users, especially when this would be displayed only for few seconds before the page reload happens.
  • In one case the PR replaces reloading the page with just displaying a message: In the resume action that is invoked by the Resume button in the ReconnectionModal template. Now the page is reloaded only after server rejection, while normal failure (e.g. network issue) does not reload the page. This brings parity with the default UI.
    • Reasoning: We don't want to do automatic reload after failed resume from a graceful pause.
  • Adds E2E tests that check reconnection behavior without server state.
    • These emulate the situation when the server restarted and has lost state for the client's circuit.

Fixes #64228

Copilot AI review requested due to automatic review settings December 11, 2025 09:30
@oroztocil oroztocil requested a review from a team as a code owner December 11, 2025 09:30
@oroztocil oroztocil requested a review from javiercn December 11, 2025 09:31
@github-actions github-actions bot added the area-blazor Includes: Blazor, Razor Components label Dec 11, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the Blazor reconnection experience when the server restarts by restoring the automatic page reload behavior that existed in .NET 9. The changes ensure that when a circuit cannot be resumed (e.g., because the server restarted and the circuit state is no longer available), the page automatically reloads instead of requiring manual user intervention.

Key Changes

  • Modified server-side ComponentHub to return null instead of sending a client error when circuit state is unavailable during resume, allowing client-side reconnection logic to handle the rejection gracefully
  • Updated client-side reconnection handlers to automatically reload the page when resume is rejected by the server
  • Improved reconnection UI to avoid flickering between "reconnect" and "pause" states during automatic reconnection attempts

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Components/Server/src/ComponentHub.cs Removed error notification to client when circuit state is unavailable, returning null instead to allow graceful handling by client reconnection logic
src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectionHandler.ts Removed unnecessary pause state transition during reconnection, calling rejected() directly when resume fails
src/Components/Web.JS/src/Platform/Circuits/DefaultReconnectDisplay.ts Updated error message and button visibility for resume failures; changed rejected resume to call rejected() instead of failed()
src/Components/Web.JS/src/Platform/Circuits/UserSpecifiedDisplay.ts Added remote field tracking and updated to pass remote flag in resume-failed events; changed reconnect default to true
src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/ReconnectModal.razor Updated resume button visibility and error message to show retry option
src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Layout/ReconnectModal.razor.js Added modal close before reload on rejection; changed exception handling in resume to show failed state instead of reloading

@oroztocil
Copy link
Member Author

/backport to release/10.0

@github-actions
Copy link
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions
Copy link
Contributor

@oroztocil backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Improve Blazor reconnection experience after server restart
Applying: Update CannotResumeAppWhenPersistedComponentStateIsNotAvailable to reflect change in ResumeCircuit
Applying: Revert a minor UI change
Applying: Add E2E tests to check reconnection behavior without server state
Using index info to reconstruct a base tree...
M	src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs
Falling back to patching base and 3-way merge...
Auto-merging src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs
CONFLICT (content): Merge conflict in src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0004 Add E2E tests to check reconnection behavior without server state
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

Copy link
Member

@javiercn javiercn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@lewing
Copy link
Member

lewing commented Dec 11, 2025

/ba-g failure to download gradle added issue opened as KBE

1 similar comment
@lewing
Copy link
Member

lewing commented Dec 11, 2025

/ba-g failure to download gradle added issue opened as KBE

@lewing lewing merged commit e91b768 into main Dec 11, 2025
23 of 25 checks passed
@lewing lewing deleted the oroztocil/blazor-reconnection-fixes-main branch December 11, 2025 20:03
@dotnet-policy-service dotnet-policy-service bot added this to the 11.0-preview1 milestone Dec 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor Server app in .NET 10 fails to reconnect after server restart, unlike .NET 9

4 participants