Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this violate the type constraint?

Tags:

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?

like image 935
James Avatar asked May 03 '15 19:05

James


People also ask

What are type constraints?

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.)

What is type constraint in C#?

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.

What is the purpose of the class constraint on a type parameter?

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.

How do I restrict a generic class in C#?

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.


1 Answers

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

like image 158
Peter M Avatar answered Sep 28 '22 11:09

Peter M