WinFXGuy
WinFXGuy

Reputation: 1599

Is session storage supported in Blazor Webassembly (PWA) standalone (Not hosted in asp.net core)?

I have the following code in my class that inherits from AuthenticationStateProvider

public async override Task<AuthenticationState> GetAuthenticationStateAsync()
        {    
            if (sessionStorageService.ContainKeyAsync("UserProfile").Result)
            {
                var mAUser = await sessionStorageService.GetItemAsync<MAUser>("UserProfile");
                return await Task.FromResult(BuildAuthenticationState(mAUser));
            }
            else
            {
                return Anonymous;
            }
        }

And I get the error on line:

if (sessionStorageService.ContainKeyAsync("UserProfile").Result)

And the error is:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Cannot wait on monitors on this runtime.
System.PlatformNotSupportedException: Cannot wait on monitors on this runtime.
   at System.Threading.Monitor.ObjWait(Boolean exitContext, Int32 millisecondsTimeout, Object obj)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout, Boolean exitContext)
   at System.Threading.Monitor.Wait(Object obj, Int32 millisecondsTimeout)
   at System.Threading.ManualResetEventSlim.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.SpinThenBlockingWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWaitCore(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.InternalWait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task`1[[System.Boolean, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetResultCore(Boolean waitCompletionNotification)
   at System.Threading.Tasks.Task`1[[System.Boolean, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].get_Result()
   at MyAushadhaBlazor.Auth.AuthStateProvider.GetAuthenticationStateAsync() in C:\xxx\xxxx\xxx\xxx\xxx\BlazorApp1\Auth\AuthStateProvider.cs:line 40
   at Microsoft.AspNetCore.Components.Authorization.AuthorizeViewCore.OnParametersSetAsync()
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()

Upvotes: 0

Views: 1337

Answers (1)

Just the benno
Just the benno

Reputation: 2601

Blazor WASM has compared to Blazor Server limited support for a task scheduler. Things like .GetAwaiter().GetResult() will not work in Blazor WASM. This explains your error message

Cannot wait on monitors on this runtime

If you add an await in front of ContainKeyAsync and remove the .Result it should work.

public async override Task<AuthenticationState> GetAuthenticationStateAsync()
{    
    if (await sessionStorageService.ContainKeyAsync("UserProfile"))
    {
        var mAUser = await sessionStorageService.GetItemAsync<MAUser>("UserProfile");
        return await Task.FromResult(BuildAuthenticationState(mAUser));
    }
    else
    {
        return Anonymous;
    }
}

Upvotes: 2

Related Questions