Why does this violate the type constraint?

I’m trying to customise ASP.NET Identity 3 so that it uses integer keys:

public class ApplicationUserLogin : IdentityUserLogin<int> { }
public class ApplicationUserRole : IdentityUserRole<int> { }
public class ApplicationUserClaim : IdentityUserClaim<int> { }

public sealed class ApplicationRole : IdentityRole<int>
{
  public ApplicationRole() { }
  public ApplicationRole(string name) { Name = name; }
}

public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, int>
{
  public ApplicationUserStore(ApplicationDbContext context) : base(context) { }
}

public class ApplicationRoleStore : RoleStore<ApplicationRole, ApplicationDbContext, int>
{
  public ApplicationRoleStore(ApplicationDbContext context) : base(context) { }
}

public class ApplicationUser : IdentityUser<int>
{
}

public sealed class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
{
  private static bool _created;

  public ApplicationDbContext()
  {
    // Create the database and schema if it doesn't exist
    if (!_created) {
      Database.AsRelational().Create();
      Database.AsRelational().CreateTables();
      _created = true;
    }
  }
}

This compiles okay, but then throws a runtime error:

System.TypeLoadException

GenericArguments[0], ‘TeacherPlanner.Models.ApplicationUser’, on ‘Microsoft.AspNet.Identity.EntityFramework.UserStore`4[TUser,TRole,TContext,TKey]’ violates the constraint of type parameter ‘TUser’.

The signature for UserStore is:

public class UserStore<TUser, TRole, TContext, TKey>
where TUser : Microsoft.AspNet.Identity.EntityFramework.IdentityUser<TKey>
where TRole : Microsoft.AspNet.Identity.EntityFramework.IdentityRole<TKey>
where TContext : Microsoft.Data.Entity.DbContext
where TKey : System.IEquatable<TKey>

ApplicationUser is precisely an IdentityUser<int>. Isn’t this what it’s looking for?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Ran into this problem. It was crashing on the startup.cs file.
changed

services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

to
services.AddIdentity<ApplicationUser, ApplicationIdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext,int>()
                .AddDefaultTokenProviders();

declaring the key type seemed to get past the crash

Method 2

Ran into this problem as well. I had to add IdentityRole key type also, because it was still throwing the same error.

        services.AddIdentity<ApplicationUser, IdentityRole<int>>()
            .AddEntityFrameworkStores<ApplicationDbContext,int>()
            .AddDefaultTokenProviders();

Method 3

Note for EF Core Users

Just to add to the above, if you are using .Net core 3.0 (not sure about earlier versions), there is no longer a AddEntityFrameworkStores<TContext,TKey> method.

Instead there is a generic variant of IdentityDbContext so instead you derive your DbContext from IdentityDbContext<TUser,TRole,TKey>

e.g. in my case

class ApplicationUser : IdentityUser<int> {...}
class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<int>, int> {...}

then in your startup you can use services.AddDefaultIdentity<ApplicationUser>

cribbed from the last comment in https://github.com/aspnet/Identity/issues/1082


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x