I am trying to do something seemingly very simple. All I want to do is get the current Identity User's email address for my Blazor view. I have a UserEmailController
in my Server project, with a GetCurrent()
method that returns a Task<string>
.
public class UserEmailsController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
public UserEmailsController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
[HttpGet]
[Route("api/currentUser")]
public async Task<string> GetCurrent()
{
var user = await _userManager.GetUserAsync(User);
return await _userManager.GetEmailAsync(user);
}
}
From the spelunking I've done, it seems that the User
property on the Controller
base class should have the information loaded into it when a user is logged in, and I should be able to do something like await _userManager.GetUserAsync(User)
. However, when I break on this line, the Name
property of User
is null
, along with many of the other values. But IsAuthenticated
is true. Huh?
So, the result of the _userManager.GetUserAsync(User)
call is null
.
I've seen a few posts about this, and there are two common themes.
#1 - people try to use the User
property in the constructor of a controller and it doesn't work. The suggested solution is to use it in an Action instead, which is of course what I'm doing.
#2 - another common suggestion is to use HttpContext.User
, or to inject an IHttpContextAccessor
(added via services.AddSingleton...
or services.AddHttpContextAccessor()
). I've tried all of these approaches and I get the same result.
I found a solution here. Specifically using HttpContext.User.FindFirst(ClaimTypes.NameIdentifier)
and then passing that into _userManager.FindByIdAsync(nameId)
. Hell of a roundabout way of doing it, but it works.