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

