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

ASP.NET CORE 2 IdentityUser POCO Error


I decided to use .NET Core 2 and I am having issues. Microsoft documentation says navigation properties are no longer present in the base class IdentityUser, and I would like them back.

I can reference what role each user has in my view model, but when I put this into my application user class:

public virtual ICollection<IdentityUserRole<int>> Roles { get; } = 
  new List<IdentityUserRole<int>>();
public virtual ICollection<IdentityUserClaim<int>> Claims { get; } = 
  new List<IdentityUserClaim<int>>();
public virtual ICollection<IdentityUserLogin<int>> Logins { get; } = 
  new List<IdentityUserLogin<int>>();

and add this to my model builder:

 builder.Entity<ApplicationUser>()
    .HasMany(e => e.Claims)
    .WithOne()
    .HasForeignKey(e => e.UserId)
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

builder.Entity<ApplicationUser>()
    .HasMany(e => e.Logins)
    .WithOne()
    .HasForeignKey(e => e.UserId)
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

builder.Entity<ApplicationUser>()
    .HasMany(e => e.Roles)
    .WithOne()
    .HasForeignKey(e => e.UserId)
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

I get the error The entity type 'IdentityUserLogin<int>' requires a primary key to be defined.

Relevant Microsoft documentation is here: https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x

How can I obtain the value of User.Role for display in my view?


Solution

  • If your ApplicationUser class extends IdentityUser without using Generics to define the type of the primary key, it uses the default type, which is string.

    In that case, you have to change the type of the key in your navigation entities from int to string.

    Your ApplicationUser class should look like this

    public class ApplicationUser : IdentityUser
    {
        public virtual ICollection<IdentityUserRole<string>> Roles { get; } = new List<IdentityUserRole<string>>();
        public virtual ICollection<IdentityUserClaim<string>> Claims { get; } = new List<IdentityUserClaim<string>>();
        public virtual ICollection<IdentityUserLogin<string>> Logins { get; } = new List<IdentityUserLogin<string>>();
    }