Skip to content

[Bug]: Cannot access a disposed object #4023

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

Open
AnhNguyenDaenet opened this issue May 8, 2025 · 0 comments
Open

[Bug]: Cannot access a disposed object #4023

AnhNguyenDaenet opened this issue May 8, 2025 · 0 comments
Labels

Comments

@AnhNguyenDaenet
Copy link

AnhNguyenDaenet commented May 8, 2025

Describe the bug 🐞

When we call a js script in our C# project:

var user = await _jsRuntime.InvokeAsync<User>("signIn", _config.AzureAd.ClientId, _config.AzureAd.Authority);

A pop up will appear and we will log in with our account.

This is how the script looks like

async function signIn(clientId, authority) {
    let loginRequest = {
        prompt: 'select_account',
        scopes: ["User.Read"],
        state: btoa(Date.now()),
        sid: btoa(Date.now())
    };

    let msalConfig = {
        auth: {
            clientId: clientId,
            authority: authority,
            redirectUri: "/",
            navigateToLoginRequestUrl: true,
        },
        cache: {
            storeAuthStateInCookie: false,
            cacheLocation: "memoryStorage",
            temporaryCacheLocation: "memoryStorage"
        },
    };
    let userIdentifier = null;
    let userEmail = null;
    MSALObj = new msal.PublicClientApplication(msalConfig);
    await MSALObj.initialize();

    try {
        const authResponse = await MSALObj.loginPopup(loginRequest);
        const logoutHint = authResponse.account.idTokenClaims.login_hint;
        if (logoutHint == null) {
            console.log("No logout hint found to logout user automatically again");
        }
        userIdentifier = authResponse.account.idTokenClaims.oid;
        userEmail = authResponse.account.idTokenClaims.preferred_username;
        const handle = await MSALObj.logoutPopup({ logoutHint: logoutHint });

        console.log("returning user with id: " + authResponse?.account?.idTokenClaims?.oid + " and email: " + authResponse.account.idTokenClaims.preferred_username);
        return { UserIdentifier: authResponse.account.idTokenClaims.oid, UserEmail: authResponse.account.idTokenClaims.preferred_username };
    } catch (error) { }

    if (userIdentifier != null || userEmail != null) {
        return { UserIdentifier: userIdentifier, UserEmail: userEmail };
    }
    return null;
}

Everything is fine until this line is called:

const handle = await MSALObj.logoutPopup({ logoutHint: logoutHint });

And we got the following exception:

 ---> (Inner Exception #3) System.ObjectDisposedException: Cannot access a disposed object.
   at System.Reactive.Subjects.Subject`1.ThrowDisposed()
   at System.Reactive.Subjects.Subject`1.OnNext(T value)
   at ReactiveUI.ViewModelActivator.Deactivate(Boolean ignoreRefCount) in /_/src/ReactiveUI/Activation/ViewModelActivator.cs:line 96
   at ReactiveUI.ViewModelActivator.<Activate>b__10_0() in /_/src/ReactiveUI/Activation/ViewModelActivator.cs:line 80
   at System.Reactive.Disposables.AnonymousDisposable.Dispose()
   at System.Reactive.Disposables.Disposable.TrySetSerial(IDisposable& fieldRef, IDisposable value)
   at System.Reactive.Disposables.SerialDisposableValue.set_Disposable(IDisposable value)
   at System.Reactive.Disposables.SerialDisposable.set_Disposable(IDisposable value)
   at ReactiveUI.ViewForMixins.<>c__DisplayClass11_0.<HandleViewModelActivation>b__0(Boolean activated) in /_/src/ReactiveUI/Activation/ViewForMixins.cs:line 259
   at System.Reactive.AnonymousSafeObserver`1.OnNext(T value)
   at System.Reactive.Sink`1.ForwardOnNext(TTarget value)
   at System.Reactive.Linq.ObservableImpl.Merge`1.Observables._.InnerObserver.OnNext(TSource value)
   at System.Reactive.Sink`1.ForwardOnNext(TTarget value)
   at System.Reactive.Linq.ObservableImpl.Select`2.Selector._.OnNext(TSource value)
   at System.Reactive.Sink`1.ForwardOnNext(TTarget value)
   at System.Reactive.IdentitySink`1.OnNext(T value)
   at System.Reactive.Subjects.Subject`1.OnNext(T value)
   at ReactiveUI.Blazor.ReactiveInjectableComponentBase`1.Dispose(Boolean disposing) in /_/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs:line 135
   at ReactiveUI.Blazor.ReactiveInjectableComponentBase`1.Dispose() in /_/src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs:line 65
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.DisposeAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.Dispose(Boolean disposing)<---

We need to click the try button and sign in again to continue our process. This time, 2-factor authentication is not asking anymore.

Should we add a check in ViewModelActivator to not calling dispose method if object is already disposed?

Nuget ver:

"ReactiveUI.Blazor": "20.1.1"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant