Advanced Ajapa Yoga Kriyas and Meditations for Software Developers : Tap the power of breath, mantra, mudra, and dhyana for improved focus, peace of mind, and blissful inner connection.


Use sessionStorage and localStorage in Blazor

Traditionally developers used cookies to store small pieces of information on the client machine. Although you can use cookies in Blazor apps, there is a modern and more handy alternative -- sessionStorage and localStorage objects. Collectively called Web Storage, these two objects allow you to store arbitrary pieces of information on the client side. You can access this information using JavaScript code. To that end, this article discusses browser storage handling in Blazor Server and Blazor Web Assembly (WASM).

Browser's Web Storage comes in two flavors namely sessionStorage and localStorage. The sessionStorage is available for a page as long as it is open in a browser tab or window. The data stored in the sessionStorage is deleted when a page tab or browser window is closed. Unlike sessionStorage, the data stored in the localStorage doesn't expire when the page tab or browser window is closed.

The sessionStorage and localStorage objects can be accessed from your JavaScript code. Irrespective of the storage type both of these objects have a similar API to add, remove, and retrieve data items. These objects store data as key-value pairs. A data item can be added to the storage using setItem() method. A data item previously stored in the storage can be retrieved using getItem() method. A data item can be removed from the storage using removeItem() method. And the entire storage can be explicitly cleared using clear() method.

In order to access sessionStorage and localStorage objects from your Blazor app you need to use JavaScript Interop (JS interop) features. There are third-party NuGet packages that can also be used for this purpose. We will stick to JS interop and some inbuilt classes for our examples.

As an example, we will create a Blazor app that looks like this :

As you can see, at the top of the page there are radio buttons that allow you to pick either sessionStorage or localStorage as the data storage medium. You can specify a key name and its value in the textboxes. At the bottom there are four buttons -- Set Value, Get Value, Remove Value, and Clear for doing the respective operations.

To get started, create a new Blazor Server app or Blazor WASM app. I am going to use Blazor Server app (Empty) because we also want to look at a feature available only for Blazor Server apps later in this article. Alternatively, you can create both the type of projects and switch between them as and when necessary.

Once you create the project, add an enumeration called WebStorageType and a class called FormModel as shown below:

public enum WebStorageType
{
    SessionStorage,
    LocalStorage
}

public class FormModel
{
    public WebStorageType 
    StorageType { get; set; }
    public string Key { get; set; }
    public string Value { get; set; }
}    

We use WebStorageType enum just to improve the readability of our code. You could have also used integers or string values. The FormModel class will act as a model for Blazor's EditForm. The FormModel class has StorageType, Key, and Value properties that are bound with the radio buttons and textboxes shown above.

Now, open Index.razor component and add the following in the @code block.

@code {
    public FormModel FormData { get; set; }

    protected override void OnInitialized()
    {
        FormData = new FormModel();
    }    
}

We declared FormData property to data bind our EditForm. The FormData is initialized in the OnInitialized() life cycle method.

As explained earlier, irrespective of the storage type (sessionStorage or localStorage) the methods used such as setItem() and getItem() remain the same. We can check for WebStorageType in each and every click event handler but we will prefer to write a helper method to reduce our code.

So, add the following helper method below the OnInitialized() method.

public string GetStorageType()
{
    return FormData.StorageType switch
    {
        WebStorageType.SessionStorage => "sessionStorage",
        WebStorageType.LocalStorage => "localStorage",
        _ => "sessionStorage"
    };
}

Here, the GetStorageType() method uses the C# switch expression and returns a string -- either sessionStorage or localStorage -- depending on the WebStorageType.

Since we want to use Blazor's JavScript interop for calling the web storage API, we need to inject IJSRuntime object at the top of the component file as shown below:

@inject IJSRuntime Js

We can now write click event handlers for all the four buttons. They are shown below:

public async Task OnSetClick()
{
    await Js.InvokeVoidAsync
    ($"{GetStorageType()}.setItem", 
    FormData.Key, FormData.Value);
}    

public async Task OnGetClick()
{
    FormData.Value = await Js.InvokeAsync
    <string>($"{GetStorageType()}.getItem", 
    FormData.Key);
}

public async Task OnRemoveClick()
{
    await Js.InvokeVoidAsync
    ($"{GetStorageType()}.removeItem", 
    FormData.Key);
}

public async Task OnClearClick()
{
    await Js.InvokeVoidAsync
    ($"{GetStorageType()}.clear");
}

The OnSetClick() method handles the click event of the Set Value button. Inside, we call GetStorageType() helper method to determine which of the two radio buttons were selected. We then append the desired method name to it, setItem in this case. So, if we have selected Session Storage radio button, our string will be sessionStorage.setItem.

This is the JavaScript method name we want to call via JS interop. So, we use InvokeVoidAsync() method and pass three parameters -- Web Storage method to call, data item key, and data item value.

Other methods such as OnGetClick(), OnRemoveClick(), and OnClearClick() work in similar way and call getItem(), removeItem(), and clear() methods of the underlying Web Storage object respectively.

Note that getItem() call uses InvokeAsync() method because getItem() returns a string value to the caller. The returned value is assigned to the Value property of FormData.

This completes the @code block for now. We will now add the EditForm markup below the @code block.

<h1>Web Storage Demo</h1>
<EditForm Model="@FormData">
    <table cellpadding="10" width="80%">
        <tr>
            <td width="10%" align="right" valign="top" 
            nowrap>Storage Type : </td>
            <td valign="top">
                <InputRadioGroup 
                @bind-Value="FormData.StorageType">
                    <InputRadio 
                    Value="WebStorageType.SessionStorage">
                    </InputRadio> 
                    Session Storage
                    <br />
                    <InputRadio 
                    Value="WebStorageType.LocalStorage">
                    </InputRadio> 
                    Local Storage
                </InputRadioGroup>
            </td>
        </tr>
        <tr>
            <td align="right">Key :</td>
            <td><InputText 
            @bind-Value="FormData.Key" /></td>
        </tr>
        <tr>
            <td align="right">Value :</td>
            <td><InputText 
            @bind-Value="FormData.Value" /></td>
        </tr>
        <tr>
            <td colspan="2" align="left">
                <button type="button" 
                @onclick="@OnSetClick">Set Value</button>
                <button type="button" 
                @onclick="@OnGetClick">Get Value</button>
                <button type="button" 
                @onclick="@OnRemoveClick">Remove Value</button>
                <button type="button" 
                @onclick="@OnClearClick">Clear</button>
                
            </td>
        </tr>
    </table>
</EditForm>

Notice the code shown in bold letters. There is an EditForm component and it's Model is set to FormData object created earlier in the code. Then InputRadioGroup component is used to display the radio buttons. These radio buttons pick their value from WebStorageType enum. When you select a radio button the StorageType property of the FormData is set to the underlying enum value.

The InputText component renders the textboxes for entering the Key and the Value. They are bound to the FormData.Key and FormData.Value using @bind-Value.

The click event of the four buttons is wired to the OnSetClick(), OnGetClick(), OnRemoveClick(), and OnClearClick() methods using @onclick.

This completes Index.razor component. Run the application and try all the operations. To add a value, enter a key name and its value in the respective textboxes and click on the Set Value button. To retrieve value of a key, enter the key name in the first textbox and make the other textbox empty. Then click on the Get Value button. The second textbox will be filled with the value retrieved from the Web Storage. To delete a key, enter its name in the first textbox and then click on the Remove Value button. Finally, to clear the Web Store hit the Clear button.

You can look at the browser's sessionStorage and localStorage using developer tools. For example, the following figure shows three keys added to the sessionStorage on Microsoft Edge.

In this example we successfully persisted data items into sessionStorage and localStorage. However, this data gets stored as plain string. To make it more secure you can encrypt it before storing it into the Web Storage. Blazor Server apps can readily use what is known as Protected Browser Storage for this purpose. We will learn about the Protected Browser Storage and a few more aspects of the Web Storage in the next part of this article.

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant and trainer by profession specializing in Microsoft web development technologies. Having embraced the Yoga way of life he is also a meditation teacher and spiritual guide to his students. He is a prolific author and writes regularly about software development and yoga on his websites. He is programming, meditating, writing, and teaching for over 27 years. To know more about his ASP.NET online courses go here. More details about his Ajapa Japa and Shambhavi Mudra online course are available here.

Posted On : 07 August 2023







Advanced Ajapa Yoga Kriyas and Meditations for Software Developers : Tap the power of breath, mantra, mudra, and dhyana for improved focus, peace of mind, and blissful inner connection.