在.net core中注入依赖到automapper配置文件 - IHttpContextAccessor返回null

Jay*_*aya 5 c# asp.net-core-mvc asp.net-core

目标:要注入IHttpContextAccessor作为依赖,autmapper轮廓的构造

原因:我需要传递当前用户的身份名称,作为构建我的一个域对象的一部分

问题 获取的用户标识始终为空

到目前为止我有什么?

Startup.cs

mc.AddProfile(new DtoToOtherProfile(new HttpContextAccessor()));

//OR

var mapperConfiguration = new MapperConfiguration(mc =>
        {
            IServiceProvider provider = services.BuildServiceProvider();
            mc.AddProfile(new DtoToOtherProfile(provider.GetService<IHttpContextAccessor>()));
        });
Run Code Online (Sandbox Code Playgroud)

DtoToOtherProfile.cs

 public DtoToOtherProfile(IHttpContextAccessor httpContextAccessor)
    {
     _httpContextAccessor = httpContextAccessor;

     CreateMap<MyDto, MyOther>()
    .ConstructUsing(myDto => new myOther(myDto.prop1, myDto .prop2,  _httpContextAccessor.HttpContext.User.Identity.Name)); // the name is what i intend to pass
      // other mapping
    }
Run Code Online (Sandbox Code Playgroud)

Controller.cs

  public async Task<IActionResult> Create([FromBody]MyDto model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        // save campaign
        var myOtherModel = _mapper.Map<MyOther>(model);
        // myOtherModel.UserName is always null 
       // rest
      }
Run Code Online (Sandbox Code Playgroud)

有什么东西丢失了吗?指针好吗?

Geo*_*kis 7

我认为正确的方法不是注入IHttpContextAccessor,Profile而是创建一个单独的 IValueResolver注入IHttpContextAccessor.所以,只需执行以下操作,我想获得httpcontext的用户声明

在你的StartUp.cs内心ConfigureServices添加

 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 services.AddAutoMapper();
Run Code Online (Sandbox Code Playgroud)

使用映射创建配置文件

public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            CreateMap<QueryUniqueDto, QueryUnique>()
                .ForMember(s=>s.UserClaim,opt=>opt.ResolveUsing<IdentityResolver>());
        }
    }
Run Code Online (Sandbox Code Playgroud)

创建 IValueResolver

public class IdentityResolver : IValueResolver<QueryUniqueDto, QueryUnique, UserClaim>
  {
    private IHttpContextAccessor _httpContextAccessor;

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

    public UserClaim Resolve(QueryUniqueDto source, QueryUnique destination, UserClaim destMember, ResolutionContext context)
    {
        return Helper.GetClaimsFromUser(_httpContextAccessor.HttpContext?.User.Identity as ClaimsIdentity);
    }
  }
Run Code Online (Sandbox Code Playgroud)

那太棒了!

  • 您现在可以通过 services.AddHttpContextAccessor(); 添加服务注册。 (2认同)

juu*_*nas 1

问题是 AutoMapper 配置通常是单例的。它应该是单例的,因为构建它相当繁重。但请求中的用户名不是单例范围的。您很可能必须找到不同的解决方案,而不是使用 AutoMapper。

我想到的一种选择是:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

IServiceProvider provider = services.BuildServiceProvider();

var mapperConfiguration = new MapperConfiguration(mc =>
{
    mc.AddProfile(new DtoToOtherProfile(provider.GetRequiredService<IHttpContextAccessor>()));
});
Run Code Online (Sandbox Code Playgroud)

这将构建服务提供者并从容器中获取上下文访问器。然而,这并没有奏效。