Blazor Server ProtectedBrowserStorage 反序列化

问题描述 投票:0回答:1

我的 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 中获取数据。

browser local-storage blazor-server-side
1个回答
0
投票

我有这个解决方案:

计数器.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 组件类似。组件之间的通知还没有准备好。

© www.soinside.com 2019 - 2024. All rights reserved.