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?
A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)
C# allows you to use constraints to restrict client code to specify certain types while instantiating generic types. It will give a compile-time error if you try to instantiate a generic type using a type that is not allowed by the specified constraints.
Object, you'll apply constraints to the type parameter. For example, the base class constraint tells the compiler that only objects of this type or derived from this type will be used as type arguments. Once the compiler has this guarantee, it can allow methods of that type to be called in the generic class.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With