我的 Blazor Server 应用程序有一个 AppState 类,我想使用它在组件之间进行数据交换:
public class AppState
{
public event Action OnChange;
public int Counter { get; private set; }
public void SetCounter(int num)
{
Counter = num;
NotifyStateChanged();
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
将其保存在 Counter.cs 中:
private async Task IncrementCount()
{
currentCount++;
var appState = new AppState { Counter = currentCount };
await SessionStorage.SetAsync(nameof(AppState), JsonSerializer.Serialize(appState));
}
但是当我想将其加载到 Weather.razor.cs 组件中时,我收到此错误:
JSON 值无法转换为 AppState。
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
state = (await SessionStorage.GetAsync<AppState>(nameof(AppState))).Value;
}
}
我尝试反序列化它,但 VS 给出了这个错误:
参数 1:无法从“AppState”转换为“System.IO.Stream”
state = JsonSerializer.Deserialize<AppState?>((await SessionStorage.GetAsync<AppState>(nameof(AppState))).Value);
所以我不知道如何从 ProtectedBrowserStorage 中获取数据。
我有这个解决方案:
计数器.cs
[Serializable]
public record Counter
{
public int Number { get; set; }
}
AppState.cs
public class AppState
{
public event Action? OnChange;
public ProtectedSessionStorage SessionStorage { get; set; }
public AppState(ProtectedSessionStorage sessionStorage)
{
SessionStorage = sessionStorage;
}
public async Task SetCounter(Counter counter)
{
await SessionStorage.SetAsync(nameof(Counter), JsonSerializer.Serialize(counter));
NotifyStateChanged();
}
public async Task<Counter?> GetCounter()
{
NotifyStateChanged();
var savedStateJson = await SessionStorage.GetAsync<string>(nameof(Counter));
if (savedStateJson.Success)
{
return JsonSerializer.Deserialize<Counter>(savedStateJson.Value!);
} else
{
return new Counter { Number = 0 };
}
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
计数器.cs
@page "/counter"
@rendermode InteractiveServer
@inject AppState AppState
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
currentCount = (await AppState.GetCounter())?.Number ?? 0;
await InvokeAsync(StateHasChanged);
}
}
private async Task IncrementCount()
{
currentCount++;
await AppState.SetCounter(new Data.Counter { Number = currentCount });
}
}
Weather.razor.cs 组件类似。组件之间的通知还没有准备好。