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

ASP.NET Core Web API:如何显示用户及其对应角色

问题场景

在ASP.NET Core 6 Web API中实现ASP.NET Identity,现有实体、DTO、AutoMapper配置如下,当前获取用户的方法仅能返回用户基础信息,无法关联展示用户对应的角色,需要实现UserName | FirstName | LastName | Role的展示格式。

现有实体类

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

public class ApplicationRole : IdentityRole
{
    public ICollection<ApplicationUserRole> UserRoles { get; set; }
}

public class ApplicationUserRole : IdentityUserRole<string>
{
    public virtual ApplicationUser User { get; set; }
    public virtual ApplicationRole Role { get; set; }
}

现有DTO类

public class AllRoleListDto
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class AllUserListDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Fullname
    {
        get { return FirstName + " " + LastName; }
    }
}

现有AutoMapper配置

public class AdminMapperProfile: Profile
{
    public AdminMapperProfile()
    {
        CreateMap<ApplicationUser, AllUserListDto>().ReverseMap();
        CreateMap<ApplicationRole, AllRoleListDto>().ReverseMap();
    }
}

当前获取用户的方法

public async Task<PagedResponse<AllUserListDto>> GetAllUserAsync(int page, int limit)
{
    var response = new PagedResponse<AllUserListDto>();

    try
    {
        if (page >= 1 && limit >= 1)
        {
            var userQueryable = _context.ApplicationUsers.AsQueryable();
            var pagedUsers = await userQueryable.ToPagedListAsync(page, limit);

            response.Result = _mapper.Map<List<AllUserListDto>>(pagedUsers.ToList());
            response.TotalPages = pagedUsers.PageCount;
            response.Page = pagedUsers.PageNumber;
            response.PerPage = pagedUsers.PageSize;
        }
        else
        {
            response.Error = new ErrorResponseDto()
            {
                ErrorCode = 400,
                Message = "The page number and page size must be greater than 1!"
            };
        }
    }
    catch (Exception ex)
    {
        response.Error = new ErrorResponseDto()
        {
            ErrorCode = 500,
            Message = ex.Message
        };
    }

    return response;
}
解决方案

需要从DTO扩展、AutoMapper配置、查询逻辑三个层面修改,实现用户与角色的关联展示:

1. 扩展DTO类

在AllUserListDto中添加角色属性,支持单个或多个角色展示:

public class AllUserListDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Fullname
    {
        get { return FirstName + " " + LastName; }
    }
    // 单个角色展示(取用户第一个角色)
    public string Role { get; set; }
    // 可选:多个角色展示,用逗号分隔
    // public string Roles { get; set; }
}

2. 更新AutoMapper映射规则

配置从ApplicationUser到DTO的角色映射逻辑:

public class AdminMapperProfile: Profile
{
    public AdminMapperProfile()
    {
        CreateMap<ApplicationUser, AllUserListDto>()
            // 映射单个角色,无角色时显示默认值
            .ForMember(dest => dest.Role, opt => opt.MapFrom(src => 
                src.UserRoles?.FirstOrDefault()?.Role.Name ?? "No Role"))
            // 可选:映射多个角色为逗号分隔字符串
            // .ForMember(dest => dest.Roles, opt => opt.MapFrom(src => 
            //     src.UserRoles != null ? string.Join(", ", src.UserRoles.Select(ur => ur.Role.Name)) : "No Role"))
            .ReverseMap();
            
        CreateMap<ApplicationRole, AllRoleListDto>().ReverseMap();
    }
}

3. 修改查询逻辑,预加载关联数据

使用Include和ThenInclude预加载用户的角色关联数据,避免延迟加载导致的空值:

public async Task<PagedResponse<AllUserListDto>> GetAllUserAsync(int page, int limit)
{
    var response = new PagedResponse<AllUserListDto>();

    try
    {
        if (page >= 1 && limit >= 1)
        {
            // 预加载UserRoles及关联的Role实体
            var userQueryable = _context.ApplicationUsers
                .Include(u => u.UserRoles)
                .ThenInclude(ur => ur.Role)
                .AsQueryable();
                
            var pagedUsers = await userQueryable.ToPagedListAsync(page, limit);

            response.Result = _mapper.Map<List<AllUserListDto>>(pagedUsers.ToList());
            response.TotalPages = pagedUsers.PageCount;
            response.Page = pagedUsers.PageNumber;
            response.PerPage = pagedUsers.PageSize;
        }
        else
        {
            response.Error = new ErrorResponseDto()
            {
                ErrorCode = 400,
                Message = "The page number and page size must be greater than 1!"
            };
        }
    }
    catch (Exception ex)
    {
        response.Error = new ErrorResponseDto()
        {
            ErrorCode = 500,
            Message = ex.Message
        };
    }

    return response;
}

补充说明

  • 如果用户存在多角色场景,建议使用多角色展示的DTO属性,提升数据完整性;
  • 确保DbContext已正确配置实体间的导航关系,否则Include无法正常加载关联数据;
  • 可根据业务需求调整角色的展示格式,比如将多角色转为数组或自定义分隔符的字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 11:39:35