I would like to know how I can access the current user ID inside AutoMapper when using Identity Framework.
{
public class MovieDto
{
public int Id { get; set; }
public string Name { get; set; }
public bool HasLiked { get; set; } // indicates if the current has liked the movie
...
}
}
I would like to be able to access ClaimsPrincipal
from inside AutoMapper profile, for example:
CreateMap<Movie, MovieDto>()
.ForMember(dst => dst.HasLiked, opt => opt.MapFrom(src =>
src.UserLike.Any(ul =>
ul.UserId == User.FindFirst(ClaimTypes.NameIdentifier)?.Value));
Is it possible to achieve that with AutoMapper?
If that is not possible or not indicated, what should I do perform such query in my repository in a reusable way?
After @LucianBargaoanu comment, I was able to figure out how to do this properly, so I've decided to answer to help others starting with .Net:
Create a currentUserId
to hold the user id.
public class AutoMapperProfiles : Profile
{
public AutoMapperProfiles()
{
string currentUserId = null;
CreateMap<Movie, MovieDto>()
.ForMember(dst => dst.HasLiked, opt => opt.MapFrom(src =>
src.UserLikes.Any(ul => ul.UserId == currentUserId)));
}
}
When projecting using AutoMapper, pass currentUserId
as a parameter:
public async Task<MovieDto> GetMoviesdAsync(string userId)
{
return await _context.Movies
.ProjectTo<MovieDto>(_mapper.ConfigurationProvider, new { currentUserId = userId })
.ToListAsync();
}
And, this is how I get the UserId in the Controller:
[HttpGet]
public async Task<ActionResult<IEnumerable<MovieDto>>> GetMovies()
{
var userId = User.GetUserId();
return Ok(await _unitOfWork.AuctionRepository.GetMoviesdAsync(userId));
}
This is the extensions method that I use to get the UserId:
public static class ClaimsPrincipleExtension
{
public static string GetUserId(this ClaimsPrincipal user)
{
return user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
}
}