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