Skip to content

WebViewJSRuntime should throw JSDisconnectedException when PageContext is disposed (parity with RemoteJSRuntime) #66255

@mattleibow

Description

@mattleibow

Description

When a BlazorWebView page reloads (e.g., location.reload(), Android app foregrounded after being backgrounded), the old PageContext is disposed via WebViewManager.AttachToPageAsync(). During disposal, components implementing IAsyncDisposable may invoke JS interop on IJSObjectReference — following Microsoft's recommended cleanup pattern.

These JS calls go through WebViewJSRuntime.BeginInvokeJS()IpcSender → the reloaded page's JS context, where the old JS object IDs no longer exist. This produces an unhandled JSException: JS object instance with ID X does not exist (has it been disposed?).

In Blazor Server, RemoteJSRuntime handles this correctly by throwing JSDisconnectedException when the circuit is disposed (#32901). WebViewJSRuntime has no equivalent guard.

Reproduction

https://github.com/mattleibow/MauiBlazorReloadIssue

  1. Run the MAUI Blazor Hybrid app on Windows or Android
  2. Navigate to the Weather page (implements IAsyncDisposable with IJSObjectReference)
  3. Click "Reload Page Now"
  4. Unhandled JSException occurs

The Counter page (sync IDisposable, no JS in dispose) survives reload for comparison.

Proposed Fix

  1. Add an IsDisposed / IsDisconnected flag to PageContext
  2. Set it at the start of PageContext.DisposeAsync() (before Renderer.DisposeAsync())
  3. In WebViewJSRuntime.BeginInvokeJS(), check the flag and throw JSDisconnectedException — matching RemoteJSRuntime behavior
  4. JSObjectReference.DisposeAsync() already catches JSDisconnectedException on main (Change IJSObjectReference.Dispose specifically so that it deals with catching and discarding JSDisconnectedException internally #49418)

Additionally, guard IpcSender and IpcReceiver against disposed PageContext to prevent corruption of the new page state.

Affected files

  • src/Components/WebView/WebView/src/PageContext.cs — add disposed flag
  • src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs — throw JSDisconnectedException
  • src/Components/WebView/WebView/src/IpcSender.cs — guard against disposed context
  • src/Components/WebView/WebView/src/IpcReceiver.cs — ignore messages for disposed context

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Components

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions