Closed adamfoneil closed 3 years ago
Got this working with a new FormatKey virtual method.
Implementation I'm using looks like this:
public class StateDictionary : DbDictionary<string>
{
private readonly string _userName;
public StateDictionary(DapperCX<int, User> data) : base(data.GetConnection, "dbo.StateDictionary")
{
_userName = data.User.Name;
}
protected override string FormatKey(string key) => $"{_userName}-{key}";
protected override TValue Deserialize<TValue>(string value) => JsonSerializer.Deserialize<TValue>(value);
protected override string Serialize<TValue>(TValue value) => JsonSerializer.Serialize(value);
}
In use, it looks like this. The point of this is to remember the state of filter and paging controls
without some kind of state management, navigating around a Blazor app causes components to revert to their default state, meaning that filters, sort options, and page controls all lose their values. This would be very poor user experience to have to keep starting over with every interaction.
@inject StateDictionary State
const string storageKey = "company-query";
protected override async Task OnInitializedAsync()
{
query = (await State.GetAsync<CompanyQuery>(storageKey)) ?? new CompanyQuery() { DataOwnerId = Data.User.DataOwnerId, Page = 0 };
// some code omitted for clarity
}
Broadly speaking, I'm not sure there's a compelling reason to use DbDictionary
as an ISession
replacement. I think I learned an aversion to using Session for anything from pre-.NET Core days. But I actually like .NET Core ISession
functionality.
This would make
DbDictionary
more easily usable as a state dictionary in Blazor. By automatically prefixing keys with the current user name, you'd get automatic user isolation of state data. This came up as I worked through Blazor state options described here. I tried browser storage, and there are complications regarding pre-rendered html. I knew thatDbDictionary
was an option, but it needs an easier way to isolate content by user.