8
votes

So basically after finally learning how to change OpenAuth to not use DefaultConnection in .NET 4.5, I've moved on to 4.5.1, rendering those learnings moot. The duties of AuthConfig.cs now reside in Startup.Auth.cs, The static methods of OpenAuth have been abstracted away and therefore I can no longer change the default value of OpenAuth.ConnectionString directly.

What is the best practice for changing Membership's connection string/database in .NET 4.5.1?

2

2 Answers

13
votes

I have followed the approach you suggested and it worked for me. However, there were few things mostly syntactic and naming issues which happened to be different. I think these differences are due to probably the different versions of Visual Studios we used (rather than .NET - my version is release one with .NET 4.5.1). I continue with a description of my specific solution.

My goal was to have a single DB context with which I can access both User or Identity related data and also my custom application data. To achieve this I completely deleted class ApplicationDbContext which is automatically created for you when you create a new project.

Then, I created a new class MyDbContext.

public class MyDbContext: DbContext
{
    public MyDbContext() : base("name=DefaultConnection")
    {

    }

    //
    // These are required for the integrated user membership.
    //
    public virtual DbSet<IdentityRole> Roles { get; set; }
    public virtual DbSet<ApplicationUser> Users { get; set; }
    public virtual DbSet<IdentityUserClaim> UserClaims { get; set; }
    public virtual DbSet<IdentityUserLogin> UserLogins { get; set; }
    public virtual DbSet<IdentityUserRole> UserRoles { get; set; }

    public DbSet<Movie> Movies { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<Purchase> Purchases { get; set; }
}

The fields Roles, Users, UserClaims, UserLogins, UserRoles are as suggested required for the membership management. However, in my case their types have different names (ApplicationUser instead of User, IdentityUserClaim instead of UserClaim and etc.). I suppose that was the reason why Antevirus had the "User could not be found" problem.

Also, as we see in my case there are 5 such fields rather than 8. Probably, this is due to the different versions of the Visual Studio.

The last change which I made was in class AccountController and it reflects the use of the new context MyDbContext. Here I passed an instance of MyDbContext instead of ApplicationDbContext

Before

public AccountController()
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}

After

public AccountController()
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext())))
{
}
8
votes

Release Candidate

Works with Microsoft.AspNet.Identity.EntityFramework 1.0.0-rc1

In the parameterless constructor for AccountController, change the line

IdentityManager = new AuthenticationIdentityManager(new IdentityStore());

to

IdentityManager = new AuthenticationIdentityManager(new IdentityStore(new DefaultIdentityDbContext("YourNameOrConnectionString")));

and you're good to go.

Release

Works with Microsoft.AspNet.Identity.EntityFramework 1.0.0

Similar to what we did for release candidate, but we do this in a different place. Open IdentityModels.cs that was created as part of the VS template and add the following constructor to the ApplicationDbContext class:

public ApplicationDbContext(string nameOrConnectionString)
    : base(nameOrConnectionString)
{
}

and you can now change the parameterless constructor in AccountController from

public AccountController()
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{
}

to

public AccountController()
    : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext("YourNameOrConnectionString"))))
{
}

and your done.