Skip to content
This repository was archived by the owner on Dec 26, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Project>

<PropertyGroup Label="Package Versions">
<DotNet3Version>3.1.14</DotNet3Version>
<DotNet5Version>5.0.5</DotNet5Version>
<DotNet6Version>6.0.12</DotNet6Version>
<DotNet7Version>7.0.1</DotNet7Version>
</PropertyGroup>

</Project>
37 changes: 35 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ builder.Services.AddBlazoredSessionStorage(config => {
```

### SetItem[Async] method now serializes string values
Prior to v2 we bypassed the serialization of string values as it seemed a pointless as string can be stored directly. However, this led to some edge cases where nullable strings were being saved as the string `"null"`. Then when retrieved, instead of being null the value was `"null"`. By serializing strings this issue is taken care of.
Prior to v2 we bypassed the serialization of string values as it seemed pointless as string can be stored directly. However, this led to some edge cases where nullable strings were being saved as the string `"null"`. Then when retrieved, instead of being null the value was `"null"`. By serializing strings this issue is taken care of.
For those who wish to save raw string values, a new method `SetValueAsString[Async]` is available. This will save a string value without attempting to serialize it and will throw an exception if a null string is attempted to be saved.

## Installing
Expand All @@ -42,7 +42,7 @@ You can also install via the .NET CLI with the following command:
dotnet add package Blazored.SessionStorage
```

If you're using Visual Studio you can also install via the built in NuGet package manager.
If you're using Jetbrains Rider or Visual Studio you can also install via the built in NuGet package manager.

## Setup

Expand All @@ -69,6 +69,17 @@ public static async Task Main(string[] args)
}
```

### Registering services as Singleton - Blazor WebAssembly **ONLY**
99% of developers will want to register Blazored SessionStorage using the method described above. However, in some very specific scenarios,
developers may have a need to register services as Singleton as apposed to Scoped. This is possible by using the following method:

```csharp
builder.Services.AddBlazoredSessionStorageAsSingleton();
```

**This method will not work with Blazor Server applications as Blazor's JS interop services are registered as Scoped and cannot be injected into Singletons.**


## Usage (Blazor WebAssembly)
To use Blazored.SessionStorage in Blazor WebAssembly, inject the `ISessionStorageService` per the example below.

Expand Down Expand Up @@ -128,9 +139,11 @@ The APIs available are:
- GetItemAsync()
- GetItemAsStringAsync()
- RemoveItemAsync()
- RemoveItemsAsync()
- ClearAsync()
- LengthAsync()
- KeyAsync()
- KeysAsync()
- ContainKeyAsync()

- synchronous via `ISyncSessionStorageService` (Synchronous methods are **only** available in Blazor WebAssembly):
Expand All @@ -139,9 +152,11 @@ The APIs available are:
- GetItem()
- GetItemAsString()
- RemoveItem()
- RemovesItem()
- Clear()
- Length()
- Key()
- Keys()
- ContainKey()

**Note:** Blazored.SessionStorage methods will handle the serialisation and de-serialisation of the data for you, the exception is the `GetItemAsString[Async]` method which will return the raw string value from session storage.
Expand Down Expand Up @@ -178,6 +193,24 @@ You can find an example of this in the Blazor Server sample project. The standar
## Testing with bUnit
This library provides test extensions for use with the [bUnit testing library](https://bunit.dev/). Using these test extensions will provide an in memory implementation which mimics session storage allowing more realistic testing of your components.

### Installing

To install the package add the following line to you csproj file replacing x.x.x with the latest version number (found at the top of this file):

```
<PackageReference Include="Blazored.SessionStorage.TestExtensions" Version="x.x.x" />
```

You can also install via the .NET CLI with the following command:

```
dotnet add package Blazored.SessionStorage.TestExtensions
```

If you're using Jetbrains Rider or Visual Studio you can also install via the built in NuGet package manager.

### Usage example

Below is an example test which uses these extensions. You can find an example project which shows this code in action in the samples folder.

```c#
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>

<Authors>Chris Sainty</Authors>
<Company></Company>
Expand All @@ -26,12 +26,16 @@
<AssemblyOriginatorKeyFile>Blazored.SessionStorage.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup>
<None Include="..\Blazored.SessionStorage\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="bunit.core" Version="1.12.6" />
<PackageReference Include="bunit.core" Version="1.13.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace Blazored.SessionStorage.TestExtensions
{
internal class InMemoryStorageProvider : IStorageProvider
{
private readonly Dictionary<string, string> _dataStore = new Dictionary<string, string>();
private readonly Dictionary<string, string> _dataStore = new();

public void Clear()
=> _dataStore.Clear();

public ValueTask ClearAsync(CancellationToken? cancellationToken = null)
public ValueTask ClearAsync(CancellationToken cancellationToken = default)
{
_dataStore.Clear();
return new ValueTask(Task.CompletedTask);
Expand All @@ -21,35 +21,56 @@ public ValueTask ClearAsync(CancellationToken? cancellationToken = null)
public bool ContainKey(string key)
=> _dataStore.ContainsKey(key);

public ValueTask<bool> ContainKeyAsync(string key, CancellationToken? cancellationToken = null)
=> new ValueTask<bool>(ContainKey(key));
public ValueTask<bool> ContainKeyAsync(string key, CancellationToken cancellationToken = default)
=> new(ContainKey(key));

public string GetItem(string key)
=> _dataStore.ContainsKey(key) ? _dataStore[key] : default;
=> _dataStore.TryGetValue(key, out var value) ? value : default;

public ValueTask<string> GetItemAsync(string key, CancellationToken? cancellationToken = null)
=> new ValueTask<string>(GetItem(key));
public ValueTask<string> GetItemAsync(string key, CancellationToken cancellationToken = default)
=> new(GetItem(key));

public string Key(int index)
=> index > _dataStore.Count - 1 ? default : _dataStore.ElementAt(index).Key;

public ValueTask<string> KeyAsync(int index, CancellationToken? cancellationToken = null)
=> new ValueTask<string>(Key(index));
public IEnumerable<string> Keys()
=> _dataStore.Keys.ToList();

public ValueTask<string> KeyAsync(int index, CancellationToken cancellationToken = default)
=> new(Key(index));

public ValueTask<IEnumerable<string>> KeysAsync(CancellationToken cancellationToken = default)
=> new(_dataStore.Keys.ToList());

public int Length()
=> _dataStore.Count;

public ValueTask<int> LengthAsync(CancellationToken? cancellationToken = null)
=> new ValueTask<int>(Length());
public ValueTask<int> LengthAsync(CancellationToken cancellationToken = default)
=> new(Length());

public void RemoveItem(string key)
=> _dataStore.Remove(key);

public ValueTask RemoveItemAsync(string key, CancellationToken? cancellationToken = null)
public ValueTask RemoveItemAsync(string key, CancellationToken cancellationToken = default)
{
RemoveItem(key);
return new ValueTask(Task.CompletedTask);
}

public void RemoveItems(IEnumerable<string> keys)
{
foreach (var key in keys)
{
_dataStore.Remove(key);
}
}

public ValueTask RemoveItemsAsync(IEnumerable<string> keys, CancellationToken cancellationToken = default)
{
RemoveItems(keys);

return new ValueTask(Task.CompletedTask);
}

public void SetItem(string key, string data)
{
Expand All @@ -63,7 +84,7 @@ public void SetItem(string key, string data)
}
}

public ValueTask SetItemAsync(string key, string data, CancellationToken? cancellationToken = null)
public ValueTask SetItemAsync(string key, string data, CancellationToken cancellationToken = default)
{
SetItem(key, data);
return new ValueTask(Task.CompletedTask);
Expand Down
18 changes: 7 additions & 11 deletions src/Blazored.SessionStorage/Blazored.SessionStorage.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFrameworks>netstandard2.1;net7.0</TargetFrameworks>
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>

<Authors>Chris Sainty</Authors>
<Company></Company>
Expand All @@ -26,20 +26,16 @@
<AssemblyOriginatorKeyFile>Blazored.SessionStorage.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.1' OR '$(TargetFramework)' == 'netcoreapp3.1'">
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1' OR '$(TargetFramework)' == 'netcoreapp3.1'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.31" />
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="$(DotNet6Version)" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="$(DotNet7Version)" />
</ItemGroup>

<ItemGroup>
Expand All @@ -62,4 +58,4 @@
</AssemblyAttribute>
</ItemGroup>

</Project>
</Project>
Loading