维护 Blazor 服务器应用程序中的状态

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

我有一个 Blazor 服务器应用程序,其中注册了一个服务来维护状态,如下所示:


    public class AppState
    {
        
        public bool IsAuthenticated { get; set; }
        public string UserId { get; set; }
    }

program.cs

    builder.Services.AddScoped<AppState>();

Index.razor
OnInitialized()
我在 AppState 中设置了一些值:


    @inject AppState AppState
    protected override void OnInitialized()
    {
      AppState.UserId = "logged in userid";
    }

我将此服务注入到组件中,以获取范围服务所需的任何内容。

但是,如果我在 DataService.cs(也在范围内)中执行此操作并创建 ApplicationDbContext 的实例:


    public class DataService
    {
      private IServiceScopeFactory _scopeFactory;
      private AppState _appState;
      public DataService(IServicesScopeFactory scopeFactory, AppState appState)
      {
         _scopeFactory = scopeFactory;
         _appState = appState;
      } 
      
      public async Task<List<Patient>> GetAllPatientsAsync()
      {
        List<Patient> patients = new List<Patient>();
        using (var scope = _scopeFactory.CreateScope())
        {
            var context = 
            scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
            
            //access the ApplicationDbContext
        }
        return patients;
      }
    
        public class ApplicationDbContext : IdentityDbContext
        {
            public Guid _tenantId;
            AppState _state;
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> 
                 options, ITenantProvider _tenantProvider, AppState appState)
                : base(options)
            {
                _tenantId = _tenantProvider.GetTenantId();
                _state = appState; //seems a new instance of AppState is provided 
                                                           here...
            }

似乎 AppState 已重新初始化(在新创建的 ApplicationDbContext 内),并且我没有获得在 Index.razor 中设置的 userId 的值。在我看来,当我使用 ScopeFactory 创建一个范围并从该范围调用 ApplicationDbContext 时,就会创建一个新的 AppState 范围实例。

这个问题有什么解决办法吗?我需要保留原来的 AppState。

asp.net-core blazor
1个回答
0
投票

您可以使用会话存储来维护状态。这里只是示例代码供您参考:

AppState.cs:

namespace BlazorSessionAppState.Data
{
    public class AppState
    {
        public bool IsAuthenticated { get; set; }
        public string UserId { get; set; }
    }

}

索引.剃刀:

@page "/"
@using BlazorSessionAppState.Data
@inject BlazorSessionAppState.Services.SessionStorageService SessionService
<h3>Blazor Server Session Storage Example</h3>
<p>IsAuthenticated: @_appState?.IsAuthenticated</p>
<p>UserId: @_appState?.UserId</p>

<button @onclick="SetAppState">Set State</button>
<button @onclick="GetAppState">Get State</button>

@code {
    private AppState _appState;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _appState = await SessionService.GetAppStateAsync();
            StateHasChanged();
        }
    }

    private async Task SetAppState()
    {
        _appState = new AppState
            {
                IsAuthenticated = true,
                UserId = "TestUser123"
            };
        await SessionService.SaveAppStateAsync(_appState);
    }

    private async Task GetAppState()
    {
        _appState = await SessionService.GetAppStateAsync();
        StateHasChanged();
    }
}

SessionStorageService.cs:

using BlazorSessionAppState.Data;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using System.Text.Json;

namespace BlazorSessionAppState.Services
{
    public class SessionStorageService
    {
        private readonly ProtectedSessionStorage _sessionStorage;

        public SessionStorageService(ProtectedSessionStorage sessionStorage)
        {
            _sessionStorage = sessionStorage;
        }

        public async Task SaveAppStateAsync(AppState appState)
        {
            await _sessionStorage.SetAsync("AppState", appState);
        }

        public async Task<AppState> GetAppStateAsync()
        {
            var result = await _sessionStorage.GetAsync<AppState>("AppState");
            return result.Success ? result.Value : new AppState();
        }

    }
}

程序.cs:

builder.Services.AddScoped<SessionStorageService>(); // Register as Scoped

enter image description here

enter image description here

这里是文档链接:

https://gist.github.com/SteveSandersonMS/ba16f6bb6934842d78c89ab5314f4b56#3-browser-storage-localstoragesessionstorage

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