C
C#2w ago
prodijay

Unable to get logged in user with GetUserAsync

In my controller's post action, I am trying to obtain the logged in user to add to an instance of my Study model, to then add to the database. For context I am using ASPNET Core Identity, with cookies. After successfully using the /register and /login Identity endpoints, I attempt to use the HttpPost for the controller which contains the logic for obtaining the logged in user. However the logged in user seems to be null. I have attempted several ways, including: var user = await _userManager.GetUserAsync(HttpContext.User); This is the set up for my controller:
c#
[ApiController]
[Route("api/[controller]")]
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
c#
[ApiController]
[Route("api/[controller]")]
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
Both _userManager and HttpContext.User exist.
14 Replies
Motley
Motley2w ago
What is UserManager<T>? Is that a class you defined yourself?
prodijay
prodijay2w ago
That's something I defined myself yes. I did that because I was following a stackoverflow thread in order to try and get the logged in user: https://stackoverflow.com/questions/36641338/how-to-get-current-user-in-asp-net-core
c#
private readonly UserManager<IdentityUser> _userManager;
public CompetitionsController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}

var user = await _userManager.GetUserAsync(HttpContext.User);
c#
private readonly UserManager<IdentityUser> _userManager;
public CompetitionsController(UserManager<IdentityUser> userManager)
{
_userManager = userManager;
}

var user = await _userManager.GetUserAsync(HttpContext.User);
I've had a look at the definition of UserManager, I don't understand it completely but from what I understand, it provides methods like .GetUserAsync for the User table specified. Do let me know if you need more information. My User model extends IdentityUser as thus.
c#
public class User : IdentityUser
{
public ICollection<Study> Studies { get; set; } = new List<Study>();
}
c#
public class User : IdentityUser
{
public ICollection<Study> Studies { get; set; } = new List<Study>();
}
Also my database context ApplicationDBContext uses IdentityUser instead of User, like so:
c#
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
c#
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
I assume this is the correct way for EF. However, one thing that confuses me is that when I migrate and update my databases, I don't have a User table, but an AspNetUser table instead; I presume this is something that ASPNET Core Identity does under the hood. I don't know if this affects things.
Motley
Motley2w ago
This isn't the normal setup that I am used to. Typically for authenticated applications, once a user is authenticated, you can just get the user details like name, email, roles from the HttpContext.User without having to go through any sort of UserManager. Are you running some sort of IdentityServer?
Unknown User
Unknown User2w ago
Message Not Public
Sign In & Join Server To View
prodijay
prodijay2w ago
I agree with you, I am able to get user details via HttpContext.User such as name and email. However I just want the UserId, so that I can add it to an instance of a model and add it to the database. Do you know if this is possible with just HttpContext.User? Hi, I'll share my repo in a little bit, I just need to figure out how to hide my connection string when I push to GitHub.
Unknown User
Unknown User2w ago
Message Not Public
Sign In & Join Server To View
prodijay
prodijay2w ago
I get that, yeah
SwaggerLife
SwaggerLife2w ago
Are you using JsonWebTokens? You could store a name identifier.
Unknown User
Unknown User2w ago
Message Not Public
Sign In & Join Server To View
SwaggerLife
SwaggerLife2w ago
You are right, my bad.
Unknown User
Unknown User2w ago
Message Not Public
Sign In & Join Server To View
prodijay
prodijay2w ago
Thanks for being patient yall😙 https://github.com/jasonHYLam/csharp-test Okay here it is. The salient files should be Program.cs, Model/ApplicationDBContext.cs, Model/User.cs, Controllers/StudyController.cs The studyController is definitely a mess because I was trying so many different ways to get the logged in user. Oh and for more context, I am using this with a React SPA. Please ignore the Pages directory. The _userManager can be found on line 14 in StudyController. However I'm not using it anywhere else in the project. https://discord.com/channels/143867839282020352/156079822454390784/1253850896941711454 Last night I described how I may be be doing something wrong with my User and IdentityUser types, because I seem to be interchanging them throughout my project, which I wasn't sure if it was a problem or not.
MODiX
MODiX2w ago
prodijay
I'm facing some challenges with my User model which extends IdentityUser. My current concern is that I'm unable to get the logged in user from UserManager in my controller. I fear I'm doing something wrong in my Program.cs, ApplicationDBContext and StudyController setup, because I'm using both User and IdentityUser throughout. Should I be consistent and use only User or IdentityUser? In fact should I scrap my User model? I am expecting to have a One to Many relationship between a User (one) and Studies (many), but could/should I use IdentityUser for that instead?
c#
// Program.cs
builder.Services.AddControllers();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql("..."));
builder.Services.AddIdentityCore<User>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthorization();
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
c#
// Program.cs
builder.Services.AddControllers();
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql("..."));
builder.Services.AddIdentityCore<User>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAuthorization();
builder.Services.AddIdentityApiEndpoints<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
c#
// ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
c#
// ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
c#
// StudyController.cs
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
c#
// StudyController.cs
public class StudyController : ControllerBase
{
private readonly UserManager<User> _userManager;
private readonly ApplicationDbContext _context;

public StudyController(ApplicationDbContext context, UserManager<User> userManager)
{
_context = context;
_userManager = userManager;
}
c#
// User.cs
public class User : IdentityUser
{
public ICollection<Study> Studies { get; set; } = new List<Study>();
}
c#
// User.cs
public class User : IdentityUser
{
public ICollection<Study> Studies { get; set; } = new List<Study>();
}
Quoted by
<@114700306742378501> from #web (click here)
React with ❌ to remove this embed.
prodijay
prodijay2w ago
Okay I've just resolved the User/IdentityUser interchanging situation. So I set User where all instances of type IdentityUser used to be. I'll see how that affects _userManager.GetUserAsync(). Okay for SOME REASON that resolved me being able to get the logged in user. So what I think happened by changing all instances of <IdentityUser> to <User> is that IdentityDbContext<IdentityUser> is now IdentityDbContext<User>, such that it aligns with UserManager<User> userManager? And previously they were not aligned?