Search code examples
c#asp.net-coreasp.net-core-2.0asp.net-core-identity

ASP.NET Core 2 - GetUserIdAsync returning null Result with Guid Ids


I'm currently porting a site to ASP.NET Core 2 and am getting the following Exception thrown when I call userManager.GenerateEmailConfirmationTokenAsync(user) with a user class that extends IdentityUser<Guid>:

System.ArgumentNullException: Value cannot be null.
Parameter name: value
   at System.IO.BinaryWriter.Write(String value)
   at Microsoft.AspNetCore.Identity.DataProtectorTokenProvider`1.<GenerateAsync>d__11.MoveNext()

GenerateAsync() makes a call to UserManager.GetUserIdAsync(), which is returning the null value in Result, which Write() is complaining about, even though the User instance I'm passing through has 07c0423e-f36b-1410-8007-800000000000 in Id.

If I call userManager.GetUserIdAsync(user) directly on the same UserManager instance on which I'm calling GenerateEmailConfirmationTokenAsync() I get this same null value in Result.

Does anyone have any ideas how to resolve this?

Edit: As requested, a functional example can be found at github.com/BenjaminNolan/GetUserIdAsyncNullExample


Solution

  • The problem you have is with these lines from your User class:

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [DefaultValue("NEWSEQUENTIALID()")]
    new public Guid Id { get; set; }
    

    Your use of the new modifier here is suppressing the following compiler warning:

    'User.Id' hides inherited member 'IdentityUser.Id'.

    This warning informs you that if you access Id via a User reference (rather than e.g. a IdentityUser<Guid> reference - the base class), you will be working with a different Id property. You can see what this looks like if you inspect the value of user.Id in your controller and compare that with the value of ((IdentityUser<Guid>)user).Id (casting to the base class in order to access its Id property).

    It's easy to fix in your case - just remove the Id property from your User class: you've already specified that the existing Id property from IdentityUser<TKey> will be of type Guid and its already configured to be the key, etc.