Manish
Manish

Reputation: 1776

Database definition for Identity User - dbo.AspNetUsers and dbo.Users

I am porting an existing webapp that used Membership to a new app that uses Identity. I have updated all table definitions, created a new MVC 5 web application in VS Community Edition 2015, version 14.0.25431.01 Update 3, then brought in code from the old project, as well as some code I had tried in a project from Adam Freeman's book.

But UserManager etc seem to want both dbo.Users and dbo.AspNetUsers.

How do I initialize the Identity ApplicationDBContext so that UserManager, SignInManager etc can read from the database? Any assistance would be great.

Currently, when the Users table is named "Users", I get the following error:

Server Error in '/' Application.
Invalid object name 'dbo.AspNetUsers'.
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.AspNetUsers'.

Line 150:           User tempUser = await UserManager.FindAsync(model.UserName, model.Password);

And when the table is named "AspNetUsers" as suggested here, I get the error:

Invalid object name 'dbo.Users'.
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.Users'.

For reference, the Identity objects are not changed from the template definitions:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
            : base("IdentityEFContext", throwIfV1Schema: false)
    {
    }

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
    {
        ApplicationUserManager manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        ...
    }

public class ApplicationUser : User
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

The conventional EF code works, e.g.

private IdentityEFContext dbContext
    {
        get
        {
            return HttpContext.GetOwinContext().Get<IdentityEFContext>();
        }
    }

List<Activity> Activities = dbContext.Activities.ToList();
List<User> Users = dbContext.Users.ToList();

The context definitions outside Identity are standard EF code first:

public class IdentityEFContext : IdentityDbContext<User>
{
    public IdentityEFContext() : base("IdentityEFContext") { }

    //public DbSet<UserLogin> UserLogins { get; set; }
    //public DbSet<UserClaim> UserClaims { get; set; }
    //public DbSet<UserRole> UserRoles { get; set; }

    public DbSet<Activity> Activities { get; set; }
    //public DbSet<User> Users { get; set; }
    //public DbSet<User> AppUsers { get; set; }
    ...    
}

The table name for users is defined using Fluent

public class UserConfig : EntityTypeConfiguration<User>
{
    public UserConfig()
    {
        ToTable("AspNetUsers");
        HasKey(u => u.Id);
        ...
    }
}

Wonder if this is relevant. I tried the following, and applicationDBContext only contains roles and users. This should provide all the needed information, but thought I would report.

ApplicationDbContext db1 = context.Get<ApplicationDbContext>(); // contains ROLES And USERS
IdentityEFContext db2 = context.Get<IdentityEFContext>();       // contains all tables for all defined dbsets

Upvotes: 1

Views: 4870

Answers (1)

Cristian Szpisjak
Cristian Szpisjak

Reputation: 2469

UserModel

public class User : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> 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;
    }
}

ApplicationDbContext

public class ApplicationDbContext : IdentityDbContext<User>
{
    public ApplicationDbContext()
        : base("IdentityEFContext", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<User>()
            .ToTable("User");
    }
}

ApplicationUserManager

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
    ApplicationUserManager manager = new ApplicationUserManager(new UserStore<User>(context.Get<ApplicationDbContext>()));
    ...
}

Upvotes: 3

Related Questions