Rollie
Rollie

Reputation: 4752

How can I access the browsers localStorage in Blazor?

I want to support JWTs, so I need to keep the token around; is there some facility to access this? Or should we just be registering our own javascript function to access this functionality for now?

Edit: per advice, I attempted to use JS interop as :

<script>
    localStorage.setItem("key1", "key1data");
    Blazor.registerFunction("readStorage", (key) => {
        return localStorage.getItem(key);
    });
</script>
@if (jwtKey == null)
{
<div class="login-panel">
    <p>JWT not loaded</p>
</div>
}
else
{
<div class="login-panel">
    <p>@jwtKey</p>
</div>
}

@functions {
    public RenderFragment Body { get; set; }
    string jwtKey;

    protected override async Task OnInitAsync()
    {
        jwtKey = RegisteredFunction.Invoke<string>("readStorage", "key1");
        if (jwtKey == null)
        {
            jwtKey = "Unknown";
        }
    }
}

But this results in a WASM error in diag:

WASM: [Microsoft.AspNetCore.Blazor.Browser.Interop.JavaScriptException] Could not find registered function with name 'readStorage'. WASM: Error: Could not find registered function with name 'readStorage'.

FYI, this is in the MainLayout.cshtml of the Blazor VS boilerplate project.

(can make a new Question if appropriate; somewhat related to this one though)

Upvotes: 19

Views: 16952

Answers (6)

Vahid Farahmandian
Vahid Farahmandian

Reputation: 6568

You can use Jinget.Blazor NuGet package and then get all items from localstoragelike this:

await localStorage.SetItemAsync(key,value);//add new item to storage
await localStorage.GetItemAsync(key); //get specific item from storage
await localStorage.UpsertItemAsync(key,value); //add or update item to storage
await localStorage.GetAllAsync(); //get all items in storage
await localStorage.RemoveItemAsync(key); //remove specific item from storage
await localStorage.RemoveAllAsync(); //remove all items from storage

If you need to work with sessionStorage, same methods are available too.

Here are complete list of samples for using Jinget.Blazor: https://github.com/VahidFarahmandian/Jinget/blob/main/Tests/Jinget.Blazor.Test/Components/Pages/BrowserStorage.razor

Upvotes: 0

AlbertK
AlbertK

Reputation: 13187

Microsoft has its own package Microsoft.AspNetCore.ProtectedBrowserStorage But as of now it is not production ready yet and it is only for server side blazor.

If you don't want to have third-party dependency you can easily implement it via JS interop.

public class LocalStorage
{
    private readonly IJSRuntime _jsRuntime;

    public LocalStorage(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }

    public async Task SetAsync(string key, object value)
    {
        string jsVal = null;
        if (value != null)
            jsVal = JsonSerializer.Serialize(value);
        await _jsRuntime.InvokeVoidAsync("localStorage.setItem", 
            new object[] { key, jsVal });
    }
    public async Task<T> GetAsync<T>(string key)
    {
        string val = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
        if (val == null) return default;
        T result = JsonSerializer.Deserialize<T>(val);
        return result;
    }
    public async Task RemoveAsync(string key)
    {
        await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", key);
    }
    public async Task ClearAsync()
    {
        await _jsRuntime.InvokeVoidAsync("localStorage.clear");
    }
}

Usage:

await _localStorage.SetAsync("Test", 42);
var val = await _localStorage.GetAsync<int>("Test");
await _localStorage.RemoveAsync("Test");
await _localStorage.ClearAsync();

Upvotes: 6

Jonathan Parker
Jonathan Parker

Reputation: 6795

There is now a package called Blazor.Extensions.Storage which is a curated extension https://github.com/BlazorExtensions/Storage

Upvotes: 2

Toke Breer-Mortensen
Toke Breer-Mortensen

Reputation: 287

In case someone else is struggeling with this (as of juni-july 2018): Steve Sanderson addresses this very issue (localstorage) in his NDC conference video here: https://www.youtube.com/watch?v=JU-6pAxqAa4 from around minute 45 or so.

He uses a a nuget package for this: https://github.com/cloudcrate/BlazorStorage Usage examples on the page, so no need to repat here.

Upvotes: 3

Verbe
Verbe

Reputation: 735

It might be implemented by default into Blazor but for now I'm using: Nuget - BlazorStorage

Upvotes: 3

Flores
Flores

Reputation: 8932

For 0.1 you need to write your own javascript interop. But I believe this is something worked on, and maybe in the 0.2 release.

Alternatively (if you don't need storage between sessions) you can write your own DI singleton, like done here: https://github.com/aspnet/samples/blob/master/samples/aspnetcore/blazor/FlightFinder/FlightFinder.Client/Services/AppState.cs

Edit
There is an open PR for this, so indeed should be there soon: https://github.com/aspnet/Blazor/pull/205

Edit2 0.2 is done, but no localstorage yet. In the meantime i've developed a package for this: BlazorExtensions also on nuget

Upvotes: 8

Related Questions