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

在VS2022的ASP.NET Core Angular模板中显示用户姓名而非邮箱

解决方案:在Angular客户端显示自定义用户字段(FirstName/LastName)

要解决前端显示邮箱而非自定义姓名的问题,需要从后端配置Identity Server返回自定义字段和前端修改获取/显示逻辑两部分入手:


后端配置:让Identity Server返回自定义用户字段

默认情况下,Identity Server不会自动将ApplicationUser的自定义字段(FirstName/LastName)加入到用户的Claims集合中,需要手动配置:

方法1:实现自定义ProfileService

创建一个CustomProfileService类,实现IProfileService接口,动态将用户的自定义字段映射为标准Claims:

using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;

public class CustomProfileService : IProfileService
{
    private readonly UserManager<ApplicationUser> _userManager;

    public CustomProfileService(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var user = await _userManager.GetUserAsync(context.Subject);
        if (user == null) return;

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.GivenName, user.FirstName ?? string.Empty),
            new Claim(ClaimTypes.Surname, user.LastName ?? string.Empty)
        };

        context.IssuedClaims.AddRange(claims);
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var user = await _userManager.GetUserAsync(context.Subject);
        context.IsActive = user != null;
    }
}

在Program.cs中注册这个服务:

builder.Services.AddScoped<IProfileService, CustomProfileService>();

方法2:在用户注册时直接添加Claims

如果不需要动态获取用户信息,也可以在用户注册阶段直接将自定义字段添加为Claims:

// 注册逻辑示例
var user = new ApplicationUser 
{ 
    UserName = model.Email, 
    Email = model.Email, 
    FirstName = model.FirstName, 
    LastName = model.LastName 
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
    await _userManager.AddClaimsAsync(user, new[]
    {
        new Claim(ClaimTypes.GivenName, user.FirstName),
        new Claim(ClaimTypes.Surname, user.LastName)
    });
}

前端修改:获取并显示自定义姓名

1. 调整login-menu组件的用户数据获取逻辑

更新login-menu.component.ts中的ngOnInit方法,从用户profile中提取given_name(对应FirstName)和family_name(对应LastName)并拼接:

ngOnInit() {
    this.isAuthenticated = this.authorizeService.isAuthenticated();
    this.userName = this.authorizeService.getUser().pipe(map(u => {
        if (!u) return '';
        // 拼接名和姓,兼容不同的Claim命名方式
        return `${u.given_name || u.firstName} ${u.family_name || u.lastName}`.trim();
    }));
}

2. 更新前端模板显示

修改login-menu.html,将原来显示邮箱的部分替换为拼接后的姓名:

<!-- 替换原有的用户名显示逻辑 -->
<span *ngIf="(userName | async) as fullName">{{ fullName }}</span>

(可选)处理Profile字段映射

如果前端user.profile中没有自动映射given_name/family_name,可以在authorize.service.ts的completeSignIn方法中手动提取Claims:

public async completeSignIn(url: string): Promise<IAuthenticationResult> {
    try {
        await this.ensureUserManagerInitialized();
        const user = await this.userManager!.signinCallback(url);
        
        // 手动提取自定义Claims,兼容标准Claim类型
        const extendedProfile = {
            ...user.profile,
            given_name: user.profile.given_name || user.profile['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'],
            family_name: user.profile.family_name || user.profile['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname']
        };
        
        this.userSubject.next(extendedProfile);
        return this.success(user && user.state);
    } catch (error) {
        console.log('There was an error signing in: ', error);
        return this.error('There was an error signing in.');
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:35:51