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

ASP.NET Core 2.0 Web API:AutoMapper配置文件中获取登录用户

在ASP.NET Core 2.0中给AutoMapper配置添加当前授权用户信息

我之前在ASP.NET Core 2.0的Web API项目里刚好处理过类似的需求,要在ViewModel转DTO的AutoMapper映射中自动填充BaseEntity的审计字段(CreatedBy、ModifiedBy这些),给你两个靠谱的实现方案:

方案一:使用AutoMapper的IMappingAction(推荐)

这个方案的优势是统一处理所有需要填充审计字段的映射,不用在每个Controller里重复传参,符合DRY原则。

步骤1:注册IHttpContextAccessor

ASP.NET Core 2.0默认没有把IHttpContextAccessor注册到DI容器,所以先在Startup.cs的ConfigureServices方法里添加:

services.AddHttpContextAccessor();

步骤2:创建自定义审计字段填充Action

这个Action会注入IHttpContextAccessor来获取当前授权用户的ID,然后自动填充DTO的审计字段:

// 先定义你的BaseEntity对应的DTO基类,确保包含审计字段
public class BaseEntityDto
{
    public Guid Id { get; set; }
    public DateTime CreatedOn { get; set; }
    public Guid CreatedBy { get; set; }
    public DateTime ModifiedOn { get; set; }
    public Guid ModifiedBy { get; set; }
}

// 自定义MappingAction
public class SetAuditFieldsAction<TDto> : IMappingAction<object, TDto> where TDto : BaseEntityDto
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public SetAuditFieldsAction(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Process(object source, TDto destination, ResolutionContext context)
    {
        // 从HttpContext中获取当前用户ID(这里假设你的用户ID存在NameIdentifier声明里)
        var userIdClaim = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier);
        if (userIdClaim == null)
        {
            // 可以根据业务需求抛出异常或者做默认处理
            throw new UnauthorizedAccessException("未找到当前授权用户ID");
        }
        
        var currentUserId = Guid.Parse(userIdClaim.Value);
        
        // 填充审计字段,这里可以根据业务区分新建/更新场景,比如判断source是否是新建的ViewModel
        destination.CreatedBy = currentUserId;
        destination.CreatedOn = DateTime.UtcNow;
        destination.ModifiedBy = currentUserId;
        destination.ModifiedOn = DateTime.UtcNow;
    }
}

步骤3:在AutoMapper配置中应用这个Action

在你的ViewModel转DTO的配置文件里,给需要填充审计字段的映射添加AfterMap调用:

public class ViewModelToDtoProfile : Profile
{
    public ViewModelToDtoProfile()
    {
        // 单个映射示例
        CreateMap<ProductViewModel, ProductDto>()
            .AfterMap<SetAuditFieldsAction<ProductDto>>();
        
        // 其他需要审计字段的映射都可以复用这个Action
        CreateMap<OrderViewModel, OrderDto>()
            .AfterMap<SetAuditFieldsAction<OrderDto>>();
    }
}

方案二:映射时通过上下文传递用户ID

如果你的业务场景需要更灵活的控制(比如某些映射不需要填充审计字段),可以在Controller调用Map的时候手动传递用户ID:

步骤1:在Controller中传递用户ID

[Authorize]
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
    private readonly IMapper _mapper;

    public ProductsController(IMapper mapper)
    {
        _mapper = mapper;
    }

    [HttpPost]
    public IActionResult Create(ProductViewModel viewModel)
    {
        var currentUserId = Guid.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
        
        // 通过AutoMapper的上下文传递用户ID
        var productDto = _mapper.Map<ProductDto>(viewModel, opt => 
            opt.Items["CurrentUserId"] = currentUserId);
        
        // 后续保存逻辑...
        return Ok(productDto);
    }
}

步骤2:在AutoMapper配置中读取上下文参数

public class ViewModelToDtoProfile : Profile
{
    public ViewModelToDtoProfile()
    {
        CreateMap<ProductViewModel, ProductDto>()
            .ForMember(dest => dest.CreatedBy, opt => 
                opt.MapFrom((src, dest, _, context) => context.Items["CurrentUserId"]))
            .ForMember(dest => dest.ModifiedBy, opt => 
                opt.MapFrom((src, dest, _, context) => context.Items["CurrentUserId"]))
            .ForMember(dest => dest.CreatedOn, opt => opt.MapFrom(_ => DateTime.UtcNow))
            .ForMember(dest => dest.ModifiedOn, opt => opt.MapFrom(_ => DateTime.UtcNow));
    }
}

注意事项

  • 确保你的认证配置已经正确设置,User对象能获取到有效的用户ID声明;
  • 方案一中的SetAuditFieldsAction可以根据业务需求调整,比如区分新建和更新操作(比如通过ViewModel的Id是否为空来判断);
  • 建议使用DateTime.UtcNow而不是本地时间,避免时区问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:02:48