question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Accessing Local Storage inside `DelegatingHandler` in Blazor Server and .NET MAUI Blazor

See original GitHub issue

We need to access local storage to get the access token stored in local storage and bind it to the HTTP request but currently accessing local storage inside DelegatingHandler does not work in Blazor Server and .NET MAUI Blazor.

Here is the DelegatingHandler:

public class AuthorizationDelegatingHandler : DelegatingHandler
{
    private readonly ILocalStorageService _localStorage;

    public AuthorizationDelegatingHandler(ILocalStorageService localStorage)
    {
        _localStorage = localStorage;
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        try
        {
           // Here exception is thrown.
            LoggedInUserInfo loggedInUserInfo = await _localStorage.GetItemAsync<LoggedInUserInfo>(LocalStorageKey.LoggedInUserInfo);

            if (loggedInUserInfo != null)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", loggedInUserInfo.AccessToken);
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine("LocalStorageSerivce throws exception.");
            Console.WriteLine(exception);
        }

        HttpResponseMessage httpResponseMessage = await base.SendAsync(request, cancellationToken);

        return httpResponseMessage;
    }
}

It throws the following exception for Blazor Server:

System.InvalidOperationException: JavaScript interop calls cannot be issued at this time. This is because the component is being statically rendered. When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.
   at Microsoft.AspNetCore.Components.Server.Circuits.RemoteJSRuntime.BeginInvokeJS(Int64 asyncHandle, String identifier, String argsJson, JSCallResultType resultType, Int64 targetInstanceId) in Microsoft.AspNetCore.Components.Server.dll:token 0x60002a4+0x25
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInterop.dll:token 0x600003a+0xda
   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInterop.dll:token 0x6000038+0x0
   at Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync[TValue](IJSRuntime jsRuntime, String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInterop.dll:token 0x6000048+0xe
   at Blazored.LocalStorage.BrowserStorageProvider.GetItemAsync(String key, Nullable`1 cancellationToken) in D:\GitHub\LocalStorage\src\Blazored.LocalStorage\BrowserStorageProvider.cs:line 23
   at Blazored.LocalStorage.LocalStorageService.GetItemAsync[T](String key, Nullable`1 cancellationToken) in D:\GitHub\LocalStorage\src\Blazored.LocalStorage\LocalStorageService.cs:line 59
   at MauiBlazor.Shared.Common.AuthorizationDelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in D:\GitHub\LocalStorage\samples\MauiBlazor.Shared\Common\AuthorizationDelegatingHandler.cs:line 31

and trows following exception for .NET MAUI Blazor:

System.NullReferenceException: Object reference not set to an instance of an object.
[DOTNET]    at Microsoft.AspNetCore.Components.WebView.Services.WebViewJSRuntime.BeginInvokeJS(Int64 taskId, String identifier, String argsJson, JSCallResultType resultType, Int64 
[DOTNET] targetInstanceId) in Microsoft.AspNetCore.Components.WebView.dll:token 0x6000113+0x0
[DOTNET]    at Microsoft.JSInterop.JSRuntime.InvokeAsync[String](Int64 targetInstanceId, String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInter
[DOTNET] op.dll:token 0x600003a+0x10a
[DOTNET]    at Microsoft.JSInterop.JSRuntime.InvokeAsync[String](String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInterop.dll:token 0x6000038+0x0
[DOTNET]    at Microsoft.JSInterop.JSRuntimeExtensions.InvokeA
[DOTNET] sync[String](IJSRuntime jsRuntime, String identifier, CancellationToken cancellationToken, Object[] args) in Microsoft.JSInterop.dll:token 0x6000048+0xe
[DOTNET]    at Microsoft.JSInterop.JSRuntimeExtens07-16 00:29:47.884 I/DOTNET  (24839):    at Blazored.LocalStorage.BrowserStorageProvider.GetItemAsync(String key, Nullable`1 cancellationToke
[DOTNET] n) in Blazored.LocalStorage.dll:token 0x6000005+0x24
[DOTNET]    at Blazored.LocalStorage.LocalStorageService.<GetItemAsync>d__5`1[[MauiBlazor.Shared.Models.IdentityModels.LoggedInUserInfo, MauiBlazor.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].
[DOTNET] MoveNext() in Blazored.LocalStorage.dll:token 0x6000082+0x29
[DOTNET]    at MauiBlazor.Shared.Extensions.LocalStorageServiceExtensions.GetUserInfoAsync(ILocalStorageService localStorage) in D:\GitHub\CleanArchitecture\src\ClientApps\MauiBlazor.Shared\Extensions\Loc
[DOTNET] alStorageServiceExtensions.cs:line 19
[DOTNET]    at MauiBlazor.Shared.Common.AuthorizationDelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in D:\GitHub\CleanArchitecture\src\ClientApps\MauiBlazor.Shared\Common\Authorizat
[DOTNET] ionDelegatingHandler.cs:line 30
[DOTNET]    at System.Net.Http.Ht
[DOTNET] tpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken) in System.Net.Http
[DOTNET]    at MauiBlazor.Shared.Services.UserService.LoginAsync(LoginModel loginModel) in D:\GitHub\CleanArchitecture\src\ClientApps\MauiBlazor.Shared\Services\UserService.cs:line 128
[DOTNET]    at MauiBlazorApp.Components.IdentityComponents.Log
[DOTNET] inComponent.HandleValidSubmitAsync() in D:\GitHub\CleanArchitecture\src\ClientApps\MauiBlazorApp\MauiBlazorApp\Components\IdentityComponents\LoginComponent.razor.cs:line 51

Is there any workaround so that we can access local storage inside DelegatingHandler?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:12 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
TanvirArjelcommented, Jul 30, 2021

@mkArtakMSFT Thank you for your patience. Here is the Minimal Repo (https://github.com/TanvirArjel/LocalStorageInsideDL). To reproduce the error, just run the app and click on the Products menu.

0reactions
javiercncommented, Jan 27, 2022

@TanvirArjel it seems that you are using a custom container library, is that the case?

The Blazor server case is clear and by design. You can’t use JS interop during prerendering.

On the Maui case, it seems to be that there is a miss-configuration in your DI container lifetimes somewhere that it is causing you to receive a new instance of the IJSRuntime instead of the instance Blazor creates.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I access browser local storage in Blazor?
LocalStorage package can be used to access the browser's local storage in Blazor. For this you need to install the package and add...
Read more >
Blazored
When creating a Blazor application with a reference to Blazor.LocalStorage, the assemblies that are downloaded as part of the application seems to include...
Read more >
Connect to local web services from Android emulators and ...
Learn how a .NET MAUI app running in the Android emulator or iOS simulator can consume a ASP.NET Core web service running locally....
Read more >
How to display local image as well as resources ...
Net MAUI Blazor I can use an img tag to display an image from wwwroot folder. But how to display an image from...
Read more >
Authentication with client-side Blazor using WebAPI and ...
In this post, I show how you can build a client-side Blazor app with authentication using WebAPI and ASP.NET Core Identity.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found