使用默认MVC Authentication时,能否重写UserManager.GetRoles返回RoleId?
解决方案:获取包含ID的用户角色
你有两种靠谱的方式来实现这个需求,我分别给你拆解一下:
方式一:直接用LINQ查询(快速简单)
这是最直接的做法,不需要改动UserManager的原有逻辑,直接借助EF(或EF Core)查询关联数据即可。假设你的DbContext是ApplicationDbContext,可以这么写:
var userId = User.Identity.GetUserId(); // 或者你传入的目标UserId using (var context = new ApplicationDbContext()) { var userRoles = context.UserRoles .Where(ur => ur.UserId == userId) .Join(context.Roles, ur => ur.RoleId, r => r.Id, (ur, r) => new { RoleId = r.Id, RoleName = r.Name }) .ToList(); }
这样就能直接拿到每个角色的ID和名称,适合快速实现需求,不用折腾框架原有代码。
方式二:扩展UserManager方法(优雅复用)
如果项目里多个地方都需要获取带ID的角色信息,那可以给UserManager写一个扩展方法,而不是重写原生的GetRoles(原生方法返回IList<string>,重写会破坏原有契约,容易出问题)。
先写一个静态扩展类:
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Threading.Tasks; public static class UserManagerExtensions { public static async Task<IList<RoleInfo>> GetRolesWithIdsAsync<TUser>(this UserManager<TUser> userManager, TUser user) where TUser : class { var context = userManager.Context as ApplicationDbContext; if (context == null) throw new InvalidOperationException("无法获取数据库上下文"); var userRoles = await context.UserRoles .Where(ur => ur.UserId == userManager.GetUserId(user)) .Join(context.Roles, ur => ur.RoleId, r => r.Id, (ur, r) => new RoleInfo { Id = r.Id, Name = r.Name }) .ToListAsync(); return userRoles; } // 定义一个简单的类来存储角色ID和名称 public class RoleInfo { public string Id { get; set; } public string Name { get; set; } } }
之后就能像调用原生方法一样使用它:
var user = await _userManager.GetUserAsync(User); var rolesWithIds = await _userManager.GetRolesWithIdsAsync(user);
这种方式把逻辑封装起来,复用性强,还不会影响原生GetRoles的正常使用。
小提醒
千万别直接重写UserManager.GetRoles方法,这个是框架定义的标准方法,返回类型固定为字符串列表,强行修改返回类型会导致依赖该方法的代码全部报错,反而给自己添乱。
内容的提问来源于stack exchange,提问作者Иво Недев
相关产品推荐
相关产品推荐

