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
相关产品推荐
相关产品推荐

