Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
BlazorWebView can reload page by itself. E.g. it might happen when app is taken foreground on Android after a while.
When page is reloading, WebViewManager will try to dispose previois PageContext.
https://github.com/dotnet/aspnetcore/blob/main/src/Components/WebView/WebView/src/WebViewManager.cs#L221
PageContext disposing will causes disposing on components of the app.
Components disposing can produce calls to JS. E.g. to dispose related js components.
But Page has already a new state, old Page state is lost.
E.g. if we invoke js on IJSObjectReference, it will fail with JSException with message like 'blazor.webview.js:1 JS object instance with ID 1 does not exist (has it been disposed?).'
.
Normally app can't handle such exception and Page (already reloaded) will notified about unhandled exception and will stop working.
This issue happens only when there is resolved scoped service that implements IAsyncDisposable
which returns not completed task.
In this situation JS invoke from component dispose method could be dispatched before new page context is created.
This issue is similar to #32901
Proposed solution
- Mark PageContext as Disposed on calling PageContext .DisposeAsync
https://github.com/dotnet/aspnetcore/blob/main/src/Components/WebView/WebView/src/PageContext.cs#L57 - Mark linked WebViewJSRuntime as Disconnected. Disconnected WebViewJSRuntime should throw JSDisconnectedException on attemt to invoke JS like RemoteJSRuntime does it.
See Prevent JS interop after circuit disposal. Fixes #32808 #32901 - IpcSender. We should have special instance of IpcSender which can be linked with PageContext and do nothing if linked PageContext is disposed. This special instance on IpcSender should be passed to services in PageContext constructor (WebViewNavigationManager, WebViewJSRuntime, WebViewRenderer). This way we will protect new state of the page in webview from corruption.
- IpcReceiver. It should also ignore received message if related PageContext is disposed. Such messages processing starts at https://github.com/dotnet/aspnetcore/blob/main/src/Components/WebView/WebView/src/IpcReceiver.cs#L49
I faced this issue in MAUI HybridBlazor project but since all related code is located in this repo, I reported the issue here.
Expected Behavior
App restarts on page reload. No unhandled exception are reported to page. No JS invoked from old PageContext are sent to new Page.
Steps To Reproduce
https://github.com/crui3er/MauiHybridBlazorReloadIssue
Run app on Windows or Android (I did not test on other platfoms).
Click 'Simulate page reload' button.
Unhandled exception will happen.
Exceptions (if any)
No response
.NET Version
dotnet 7
dotnet 8
Anything else?
No response