.NET Core中如何从AutoMapper配置文件获取用户身份信息
在.NET Core中获取用户令牌并结合AutoMapper完成对象映射
我来帮你搞定这个问题!在.NET Core控制器里获取当前用户的UserId,再结合AutoMapper把EnrollSkill视图模型映射成UserSkill领域模型,其实有几种实用的方式,我给你一步步拆解清楚:
第一步:在控制器中获取当前用户的UserId
首先你需要在控制器的Action里读取用户的身份声明,.NET Core已经帮我们把用户信息封装在User属性里了。通常用户的ID会存在ClaimTypes.NameIdentifier这个Claim类型里,你可以这样获取:
// 在控制器的Action方法内获取UserId var userId = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; // 如果你的系统用了自定义的Claim类型(比如直接叫"UserId"),就换成对应的Type // var userId = User.Claims.FirstOrDefault(c => c.Type == "UserId")?.Value;
⚠️ 注意:一定要检查userId是否为空,避免后续出现空引用错误。如果为空,说明用户未认证或者令牌里没有对应的Claim,你可以返回Unauthorized()或者自定义的错误提示。
第二步:结合AutoMapper完成对象映射
这里有两种常用的方式,你可以根据自己的场景选择:
方式一:手动补充UserId(简单直接)
这种方式不需要修改AutoMapper的配置文件,先完成基础映射,再手动给UserSkill的UserId赋值:
// 先把视图模型映射成领域模型 var userSkill = _mapper.Map<UserSkill>(enrollSkillViewModel); // 手动填充UserId userSkill.UserId = userId;
这种方法适合逻辑简单的场景,代码直观,容易理解。
方式二:通过AutoMapper上下文传递参数(更优雅)
如果想让映射规则更内聚,把UserId的填充逻辑整合到AutoMapper配置里,可以用映射上下文来传递参数:
- 首先在你的AutoMapper配置文件中,配置
EnrollSkill到UserSkill的映射,通过上下文获取UserId:
public class MappingProfile : Profile { public MappingProfile() { CreateMap<EnrollSkill, UserSkill>() .ForMember(dest => dest.UserId, opt => opt.MapFrom((src, dest, _, context) => context.Items["UserId"])); } }
- 然后在控制器的Action里,映射时传入上下文参数:
var userSkill = _mapper.Map<UserSkill>(enrollSkillViewModel, opt => { opt.Items["UserId"] = userId; });
这样映射的时候,AutoMapper会自动从上下文里取出UserId并填充到UserSkill对象中,所有映射逻辑都集中在配置文件里,代码更整洁。
第三步:调用仓储服务保存数据
拿到填充好UserId的UserSkill对象后,就可以调用你的仓储服务来保存了:
// 假设你已经通过构造函数注入了仓储服务 private readonly IUserSkillRepository _userSkillRepo; private readonly IMapper _mapper; public SkillController(IMapper mapper, IUserSkillRepository userSkillRepo) { _mapper = mapper; _userSkillRepo = userSkillRepo; } public async Task<IActionResult> Enroll(EnrollSkillViewModel model) { if (!ModelState.IsValid) { return View(model); } // 获取UserId var userId = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; if (string.IsNullOrEmpty(userId)) { return Unauthorized("用户未认证或身份信息缺失"); } // 选择上面一种方式完成映射 var userSkill = _mapper.Map<UserSkill>(model, opt => opt.Items["UserId"] = userId); // 添加到仓储并保存 _userSkillRepo.Add(userSkill); await _userSkillRepo.SaveChangesAsync(); return RedirectToAction("MySkills"); }
额外注意事项
- 确保你的控制器或者Action上添加了
[Authorize]特性,这样只有认证后的用户才能访问,User属性才会有值。 - 如果你使用的是JWT令牌,要确认令牌里确实包含了对应的UserId Claim,否则会获取不到值。
- 如果你需要频繁获取UserId,可以封装一个扩展方法,比如
User.GetUserId(),简化代码:
public static class ClaimsPrincipalExtensions { public static string GetUserId(this ClaimsPrincipal principal) { return principal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; } }
这样在控制器里直接用var userId = User.GetUserId();就可以了,更简洁。
内容的提问来源于stack exchange,提问作者Sergio
相关产品推荐
相关产品推荐

