Why is EF core one-to-one relationship not working as expected?

asp.net-core-webapi c# entity-framework-core


I have a User and a RefreshToken. I need to create a one-to-one relationship between those two objects. My RefreshToken object looks like this

`public class RefreshToken
        public string RefreshTokenID { get; set; }
        public string UserId { get; set; }
        public User User { get; set; }
        public string Token { get; set; }

My User object looks like this

`public class User : IdentityUser
    public RefreshToken RefreshToken { get; set; }

Here is how I am persisting the RefreshToken for a user using _refreshTokenRepository:

`public async Task<bool> SaveAsync(User user, string newRefreshToken, CancellationToken ct = default(CancellationToken))
      if(user.RefreshToken != null) return false;
      RefreshToken rt = new RefreshToken(newRefreshToken, DateTime.Now.AddDays(5), user.Id);

      await _dbContext.RefreshTokens.AddAsync(rt);      
      await _dbContext.SaveChangesAsync(ct);
return true;

The issue happens when, user is redirected to the '/refresh' route, and when I need to check the User's refresh token against the one coming back from the client. This property check is always null:

`var user = _userManager.Users.SingleOrDefault(u => u.UserName == username);

      if(user == null || user.RefreshToken.Token != refreshToken) return BadRequest();`

The user is in fact the right user and is found, but the RefreshToken property is null.

I have tried using fluent API to create this relationship. Same outcome. The refresh tokens are successfully persisted to the database with the right user ID in the table, but the navigational property is not working. Any ideas why?

3/17/2019 5:06:09 PM

Accepted Answer

You should modify this line:

var user = _userManager.Users.SingleOrDefault(u => u.UserName == username);

By adding .Include(u => u.RefreshToken), So, the line should look like this:

var user = _userManager.Users.Include(u => u.RefreshToken).SingleOrDefault(u => u.UserName == username);

This will tell the store to also load the related RefreshToken entities.

3/17/2019 5:36:05 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow