You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor Server基于声明注入自定义对象及页面切换数据加载方案

解决方案

1. 创建用户服务与模型

先定义你的用户业务模型,再实现一个Scoped生命周期的服务,负责加载、缓存当前用户数据:

// 用户业务模型
public class AppUser
{
    public string Id { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    // 其他自定义用户属性
}

// 用户服务接口
public interface ICurrentUserService
{
    AppUser CurrentUser { get; }
    Task LoadCurrentUserAsync();
}

// 用户服务实现
public class CurrentUserService : ICurrentUserService
{
    private readonly AuthenticationStateProvider _authStateProvider;
    private readonly YourDbContext _dbContext;
    public AppUser CurrentUser { get; private set; }

    public CurrentUserService(AuthenticationStateProvider authStateProvider, YourDbContext dbContext)
    {
        _authStateProvider = authStateProvider;
        _dbContext = dbContext;
    }

    public async Task LoadCurrentUserAsync()
    {
        var authState = await _authStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity?.IsAuthenticated ?? false)
        {
            // 从Claims中取出你定义的用户唯一ID(替换为实际的Claim类型)
            var userId = user.FindFirstValue(ClaimTypes.NameIdentifier);
            
            if (!string.IsNullOrEmpty(userId))
            {
                // 从数据库加载完整用户数据
                CurrentUser = await _dbContext.AppUsers.FirstOrDefaultAsync(u => u.Id == userId);
            }
        }
        else
        {
            CurrentUser = null;
        }
    }
}

2. 注册服务

在Program.cs中将服务注册为Scoped(Blazor Server中Scoped生命周期绑定到用户的SignalR连接,每个用户对应一个实例):

builder.Services.AddScoped<ICurrentUserService, CurrentUserService>();

3. 监听导航事件自动加载用户

在主布局组件(比如MainLayout.razor)中,注入NavigationManager和用户服务,监听页面导航变化,每次切换页面时重新加载用户数据:

@inject NavigationManager NavManager
@inject ICurrentUserService CurrentUserService
@implements IDisposable

<!-- 你的布局内容 -->

@code {
    protected override async Task OnInitializedAsync()
    {
        // 页面初始化时加载一次用户数据
        await CurrentUserService.LoadCurrentUserAsync();
        // 订阅导航切换事件
        NavManager.LocationChanged += OnLocationChanged;
    }

    private async void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        // 每次页面切换时刷新用户数据
        await CurrentUserService.LoadCurrentUserAsync();
        // 通知组件更新UI
        StateHasChanged();
    }

    public void Dispose()
    {
        // 取消订阅,避免内存泄漏
        NavManager.LocationChanged -= OnLocationChanged;
    }
}

4. 在组件/页面中使用用户数据

现在可以在任意Razor组件或页面中直接注入用户服务,随时访问当前用户的属性:

@inject ICurrentUserService CurrentUserService

@if (CurrentUserService.CurrentUser != null)
{
    <div>当前用户:@CurrentUserService.CurrentUser.Username</div>
    <div>邮箱:@CurrentUserService.CurrentUser.Email</div>
}
else
{
    <div>未登录</div>
}

额外说明

  • 如果用户数据在会话中发生变更(比如修改个人信息),可以手动调用CurrentUserService.LoadCurrentUserAsync()刷新缓存。
  • Blazor Server中避免直接依赖HttpContext,使用AuthenticationStateProvider获取用户身份是框架推荐的标准方式。

内容的提问来源于stack exchange,提问作者Marvin Klein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:15:27