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

Blazor Server中如何在LoginDisplay.razor获取扩展IdentityUser的FirstName属性

解决方案:在Blazor Server的LoginDisplay中访问自定义IdentityUser属性

问题核心

context.User是ClaimsPrincipal类型,默认仅包含ASP.NET Identity基础声明(如用户名、邮箱),自定义的FirstName/LastName不会自动注入到声明中,也无法直接将ClaimsPrincipal转换为MyProjectUser,因此直接访问会失败。以下提供两种可行方案:


方案一:通过UserManager直接获取用户实例(简单直接)

修改LoginDisplay.razor,注入UserManager<MyProjectUser>后查询完整用户对象:

@using Microsoft.AspNetCore.Identity
@using MyProject.Data
@inject UserManager<MyProjectUser> UserManager

<CascadingAuthenticationState>
    <AuthorizeView>
        <Authorized>
            @{
                var currentUser = await UserManager.GetUserAsync(context.User);
            }
            <a href="Identity/Account/Manage">Hello, @currentUser?.FirstName!</a>
            <form method="post" action="Identity/Account/Logout">
                <button type="submit" class="nav-link btn btn-link">Log out</button>
            </form>
        </Authorized>
        <NotAuthorized>
            <a href="Identity/Account/Register">Register</a>
            <a href="Identity/Account/Login">Log in</a>
        </NotAuthorized>
    </AuthorizeView>
</CascadingAuthenticationState>

注意:此方法每次渲染都会查询数据库,适合小型项目或低访问量场景。


方案二:将自定义属性注入Claims(高效推荐)

通过自定义ClaimsPrincipalFactory,把FirstName/LastName添加到用户声明中,后续无需重复查询数据库:

  1. 创建自定义声明工厂类
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using MyProject.Data;

namespace MyProject
{
    public class CustomUserClaimsFactory : UserClaimsPrincipalFactory<MyProjectUser>
    {
        public CustomUserClaimsFactory(UserManager<MyProjectUser> userManager, IOptions<IdentityOptions> optionsAccessor)
            : base(userManager, optionsAccessor)
        {
        }

        protected override async Task<ClaimsIdentity> GenerateClaimsAsync(MyProjectUser user)
        {
            var identity = await base.GenerateClaimsAsync(user);
            
            // 添加自定义属性到声明
            if (!string.IsNullOrEmpty(user.FirstName))
            {
                identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FirstName));
            }
            if (!string.IsNullOrEmpty(user.LastName))
            {
                identity.AddClaim(new Claim(ClaimTypes.Surname, user.LastName));
            }
            
            return identity;
        }
    }
}
  1. 在Program.cs中注册该工厂
    找到AddDefaultIdentity的配置代码,追加注册自定义声明工厂:
builder.Services.AddDefaultIdentity<MyProjectUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<MyProjectContext>()
    .AddClaimsPrincipalFactory<CustomUserClaimsFactory>(); // 新增此行
  1. 在LoginDisplay.razor中直接从声明读取属性
@using System.Security.Claims

<CascadingAuthenticationState>
    <AuthorizeView>
        <Authorized>
            <a href="Identity/Account/Manage">Hello, @context.User.FindFirst(ClaimTypes.GivenName)?.Value!</a>
            <form method="post" action="Identity/Account/Logout">
                <button type="submit" class="nav-link btn btn-link">Log out</button>
            </form>
        </Authorized>
        <NotAuthorized>
            <a href="Identity/Account/Register">Register</a>
            <a href="Identity/Account/Login">Log in</a>
        </NotAuthorized>
    </AuthorizeView>
</CascadingAuthenticationState>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:37:08