Inherit from IdentityUser I get an error on UserManager<User>

13,154

Solution 1

Use the other UserManager

UserManager<User, long> _userManager;

You are using this UserManager which:

Represents the user manager for users where the primary key for the user is of type string.

Solution 2

When you extend with your own User class you have to provide all of the types that Identity uses.

Here is my context class, notice that i use string as key:

public class EarlyDetectionContext  
   : IdentityDbContext<User, Role, string, EDLogin, RoleUserAssociation, EDClaim>

Of course you also need to make classes for role userlogin, userclaim and userroles. Here is mine:

public class EDClaim : IdentityUserClaim<string>
{
}  
public class EDLogin : IdentityUserLogin<string>
{
}
[Table("Roles", Schema = "ED")]
public class Role : IdentityRole<string, RoleUserAssociation>
{
    [Required, Column("DisplayName")]
    public string DisplayName { get; set; }

    [Required, Column("Created")]
    public DateTime Created { get; set; }

    [Required, Column("Updated")]
    public DateTime Updated { get; set; }

    [Required, Column("Deleted")]
    public bool Deleted { get; set; }
}  
[Table("RoleUserAssociations", Schema = "ED")]
public class RoleUserAssociation : IdentityUserRole<string>
{
    //
    //  Due to Identity 2 the Id needs to of string type
    //
    [Key]
    [Required]
    public string ID { get; set; }

    //[Required, Column("User_Id")]
    //public User User { get; set; }

    //[Required, Column("Role_Id")]
    //public Role Role { get; set; }

    [Required, Column("Created")]
    public DateTime Created { get; set; }

    [Required, Column("Updated")]
    public DateTime Updated { get; set; }

    [Required, Column("Deleted")]
    public bool Deleted { get; set; }
}  
[Table("Users", Schema = "ED")]
public class User : IdentityUser<string, EDLogin, RoleUserAssociation, EDClaim>
{
    // This is needed for the new Identity 2 framework
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User, string> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }

    [Required, Column("Municipality_Id")]
    public Municipality Municipality { get; set; }

    public string PasswordSalt { get; set; }

    [Required, Column("FirstName")]
    public string FirstName { get; set; }

    [Required, Column("LastName")]
    public string LastName { get; set; }

    [Column("Title")]
    public string Title { get; set; }

    [Required, Column("Created")]
    public DateTime Created { get; set; }

    [Required, Column("Updated")]
    public DateTime Updated { get; set; }

    [Required, Column("Deleted")]
    public bool Deleted { get; set; }

    public bool Complete { get; set; }

    [Required]
    public DateTime Activated { get; set; }
}

You need to specify the key type on every class, in my case a string, in your case a long. Also notice that my claim and login classes are empty. That's ok, i don't have to add any functionality or properties in my case, but i do need to specify them.

And the GenerateUserIdentityAsync method in the User class is needed to.

In the Startup.Auth.cs file you need to add:

// Configure the db context, user manager and signin manager to use a single instance per request
        app.CreatePerOwinContext(EarlyDetectionContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);  

You also need the OWIN startup class (can be added via Right-click - Add - New Item) and the Identity.cs files.

If you can read German the take a look at this blog
It basically describes what you're trying to do. (with a db-first approach though)
Also watch his video (he speaks good english).
And part 2 of it also.

I hope this gives you enough info to move forward :)

Share:
13,154

Related videos on Youtube

VansFannel
Author by

VansFannel

I'm software architect, entrepreneur and self-taught passionate with new technologies. At this moment I am studying a master's degree in advanced artificial intelligence and (in my free time ) I'm developing an immersive VR application with Unreal Engine. I have also interested in home automation applying what I'm learning with Udacity's nanodegree course in object and voice recognition.

Updated on September 16, 2022

Comments

  • VansFannel
    VansFannel about 1 year

    I'm developing a Web Api 2.2 application with .NET Framework 4.5.1 and Asp.Net Identity 2.1.0.

    I'm not sure what I'm doing, but I want to merge my database with ASP.NET Identity database and I have done this:

    My own dbContext.

    public class EFDbContext : IdentityDbContext, IUnitOfWork
    

    My own User class.

    public class User : 
       IdentityUser<long,
                    IdentityUserLogin<long>,
                    IdentityUserRole<long>,
                    IdentityUserClaim<long>
                   >
    

    But when I do this:

    UserManager<User> _userManager;

    I get this error:

    The type Data.Models.User cannot be used as parameter of type TUser. There isn't any explicit conversion from Data.Models.User to Microsoft.AspNet.Identity.IUser<string>.

    I'm doing this because I want to have IdentityUser.Id as long instead of string.

    How can I fix this error?

    UPDATE

    After updating UserManager with:

    UserManager<User, long> _userManager;
    

    I get the three errors here:

    EFDbContext_ctx = context as EFDbContext;
    _userManager = new UserManager<User, long>(new UserStore<User>(_ctx));
    
    1. The best match of method overload for 'Microsoft.AspNet.Identity.UserManager.UserManager (Microsoft.AspNet.Identity.IUserStore )' has some invalid arguments-
    2. The type 'Data.Models.User' cannot be used as parameter of type 'TUser' type or generic method 'Microsoft.AspNet.Identity.EntityFramework.UserStore '. There is no conversion from implicit reference from 'Data.Models.User' to 'Microsoft.AspNet.Identity.EntityFramework.IdentityUser'.
    3. Argument 1: cannot be converted from 'Microsoft.AspNet.Identity.EntityFramework.UserStore' to 'Microsoft.AspNet.Identity.IUserStore'

    How can I fix this new error?

  • VansFannel
    VansFannel almost 9 years
    Thanks for your answer. Now, I have the same problem here: _userManager = new UserManager<User, long>(new UserStore<User>(_ctx));.
  • Jonesopolis
    Jonesopolis almost 9 years
    your user store should take your context as its type parameter