One way to have data persist across sessions in a client-side Blazor WebAssembly application is to write to the browser’s LocalStorage or SessionStorage collection. This will allow the user to refresh or re-open the page and have the same experience as when they last left off.
In previous tutorials, you already learned how to pass application data between different pages and components during a single session, but there are situations when you may want data to persist across sessions in your client-side application. In a server-side application, you could simply save the data into a SQL database or other store. In a WebAssembly application, however, can use the browser’s LocalStorage
or SessionStorage
collection as a backing store.
Protecting Data Storage
Though this tutorial will not be storing sensitive data, it is good practice to encrypt stored data. ASP.NET Core provides a simple data protection stack that can be used for such purposes. In the future, it may be recommended to use a package such as Microsoft’s ProtectedBrowserStorage Nuget package, which provides data protection.
As of this writing, that package is still in early development, and it cannot target netstandard, a requirement of Mono WebAssembly. Therefore, I will be using the Blazored.LocalStorage package. Simply install it via the Package Manager Console.
Install-Package Blazored.LocalStorage
Blazor.LocalStorage Setup
To use the Blazored.LocalStorage
package, you must register its service with your application’s service collection in your project’s Startup.cs file. Start by adding a using statement for the Blazored.LocalStorage
namespace to the top of Startup.cs.
using Blazored.LocalStorage;
Then, register the service in the ConfigureServices()
method of Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
services.AddBlazoredLocalStorage();
}
Now that the service is configured, go ahead and import the package’s namespace in the project’s _Imports.razor file. This will allow you to use the package in all your .razor components without having to explicitly add a using
directive for each component.
@using Blazored.LocalStorage;
You are now ready to begin writing data to the browser’s LocalStorage collection. Open Pages/Index.razor and paste the following content.
@page "/"
<h1>Your LocalStorage Note</h1>
<textarea @bind="noteContent" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>
This will display a textarea
field that will contain the content of the note. There is also a Save button, which will be used to write to the browser’s local store, and a Clear button which will clear all locally stored data.
Blazor Save to LocalStorage
To begin using Blazored.LocalStorage
, inject an instance of the desired service into your page. At the top of Index.razor , add the following line:
@inject Blazored.LocalStorage.ILocalStorageService LocalStore
Now, declare a string
variable to hold the contents of the textarea
element, and create the event handlers that will correspond to each button’s onclick
event. The shell may look like the following:
@code{
string noteContent;
public async void UpdateLocalStorage()
{
}
public async void ClearLocalStorage()
{
}
}
To write an item to LocalStorage asynchronously using Blazored.LocalStorage
, you will use a key-value structure.
await localStore.SetItemAsync(key, value);
where localStore
corresponds to the name you assigned when injecting the instance, and key
and value
are both strings.
const string noteKey = "note";
string noteContent;
public async void UpdateLocalStorage()
{
await localStore.SetItemAsync(noteKey, noteContent);
}
Blazor Clear LocalStorage
Blazored.LocalStorage
also includes convenient methods for clearing individual items by key
await localStore.RemoveItemAsync(key);
and for clearing all stored items.
await localStore.ClearAsync();
Your ClearLocalStorage
handler may look like the following:
public async void ClearLocalStorage()
{
noteContent = "";
await localStore.ClearAsync();
}
Blazor Read LocalStorage
In order for the application to populate the textarea
with the value stored in LocalStorage
, you must override the page’s OnInitialized()
method. Specifically, to read the value asynchronously, override the async
method OnInitializedAsync()
.
protected override async Task OnInitializedAsync()
{
}
In this method, you should assign the stored value to the binding variable you are using for the textarea
element, in this case noteContent
.
To fetch the value of an item from LocalStorage, you will use the item’s key
as its identifier.
protected override async Task OnInitializedAsync()
{
noteContent = await localStore.GetItemAsync<string>(noteKey);
}
The Final Product
Your completed index.razor page will look similar to the following:
@inject Blazored.LocalStorage.ILocalStorageService localStore
@page "/"
<h1>Your LocalStorage Note</h1>
<textarea @bind="noteContent" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>
@code{
const string noteKey = "note";
string noteContent;
public async void UpdateLocalStorage()
{
await localStore.SetItemAsync(noteKey, noteContent);
}
public async void ClearLocalStorage()
{
noteContent = "";
await localStore.ClearAsync();
}
protected override async Task OnInitializedAsync()
{
noteContent = await localStore.GetItemAsync<string>(noteKey);
}
}
Top comments (3)
Man you always have great articles and best presentation.
Thanks Brad!
Thanks for the encouragement, Ben!
I think the "Usefulness" of your articles, is the key. We can immediately use them. A lot of people write stuff that is too long or too specific that is "Useless". :-)