23

I am using the ASP.NET Identity Sample from the Asp-Team, and i am trying to change the database for the IdentityDbContext...

I tried it with the constructor

public MyDbContext() : base("MyConnectionString") { } // base is IdentityDbContext

like with a DbContext class.

That works well until i try to Register a User...

await IdentityStore.CreateLocalUser(user, model.Password)

returns false... no error, nothing.

Any ideas how to fix that?

Edit:

Filename is Models\AppModel.cs, there is the MyDbContext class

originally it was

public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
}

i changed it to

public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
    public MyDbContext() : base("MyConnectionString") { }
}

the connection string is working because i have other projects using the same, and they run fine.

<connectionStrings>
    <add name="MySailorContext" connectionString="Data Source=THOMAS-LAPTOP;Initial Catalog=MySailor;Integrated Security=True;Pooling=False;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
</connectionStrings>
Hao Kung
  • 28,040
  • 6
  • 84
  • 93
Nefarion
  • 872
  • 2
  • 8
  • 28
  • 1) What exactly are you trying to do? 2) Were you able to successfully create a new user in the application before you made any changes to the code, including connection strings? 3) Exactly what changes have you made to the application so far? 4) Once you changed the connection string, did you enable migrations and update the database to generate/update the schema? – RobM Aug 18 '13 at 14:57
  • 2) Yes it was successfully working 3) Only changed the Connection string and the DbContext Constructor 4) Yes i did, else i get an SqlException – Nefarion Aug 18 '13 at 15:35
  • Ok, provide some context for your changes, including the "public MyDbContext...". Still don't have answer for #1 above -- what are you trying to do? If just change the db for everything, why not just change the existing connection string in web.config? – RobM Aug 18 '13 at 16:25
  • @RobM Thats exactly the only thing i did... – Nefarion Aug 18 '13 at 18:53
  • I'm trying to help you, but you need to provide more information! Filename, contextual snippet including surrounding lines... web.config section for your connection strings. – RobM Aug 18 '13 at 19:47
  • @RobM: i'm Editing the question, this might be a lot for comments... – Nefarion Aug 19 '13 at 07:22
  • A) have you verified that the connection string is in the correct web.config file? There are several web.configs, so you need to make sure it's in the one at the site root. B) try using "name=MyConnectionString" instead. C) Post the error you're getting if these don't work. – Erik Funkenbusch Aug 19 '13 at 08:17
  • @Nefarion, one final request for your web.config (add to the question) -- minimum is the full section. I don't mean to sound rude, but it really stinks when you have to ask for stuff multiple times when trying to help someone. – RobM Aug 19 '13 at 15:44
  • Do I have to do myUser : User ? cant I implement IUser? (cant get it to work) – Poul K. Sørensen Oct 03 '13 at 18:55

7 Answers7

41

Here's a step-by-step on how to successfully change your database. First, clean-up anything you might have done previously. If there is any chance you might not get EVERYTHING, it would be best if you just started with a completely fresh copy in a new folder.

Once source is 100% back to original state, ensure everything else is cleaned up, including deleting your "new" database and the original database (aspnet-AspnetIdentitySample-20130627083537_2). You can find the original database using the SQL Server Object Explorer. ("View" -> "SQL Server Object Explorer" in Visual Studio)

Next, before you run your new application for the first time, go ahead and make the change to use your database name of choice. Here are the steps:


1. Set new database connection in web.config
  <connectionStrings>
    <!-- Original Connection String -->
    <!--
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;
         Initial Catalog=aspnet-AspnetIdentitySample-20130627083537_2;Integrated Security=True"
      providerName="System.Data.SqlClient" />
    -->
    <!-- New Connection String -->
    <add name="MyConnectionString" connectionString="Data Source=(LocalDb)\v11.0;
         Initial Catalog=MyAspnetIdentitySample_1;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

2. Modify AppModel.cs to have DBContext use new connection:

OLD:

    public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
    {
    }

NEW:

    public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
    {
        public MyDbContext() : base("MyConnectionString") { }
    }

3. Enable database migrations, create seed data and update to validate

3.1- In the package manager console, enable database migrations:

PM> enable-migrations

3.2 - Update Migrations\Configuration.cs to enable automatic migrations and seed data

    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

    protected override void Seed(AspnetIdentitySample.Models.MyDbContext context)
    {

        context.Users.AddOrUpdate(
            p => p.UserName,
            new MyUser { UserName = "John Doe" }
        );
    }

3.3 - Create the database through migration. In the Package Manager Console:

PM> update-database

3.4 - Validate that your new database was created (and that the originally provided db name doesn't exist) by using SQL Server Object Explorer and looking for the database "MyAspnetIdentitySample_1".

4. Run the app and create a new login to verify

This is how you can successfully do it from scratch -- without you providing more detail, I can't troubleshoot it with/for you. You should be able to determine where you went wrong.

RobM
  • 3,588
  • 2
  • 19
  • 14
  • I am using code-first and the EF model is successfully running already, i wanted to add the login stuff today, and it is not working... – Nefarion Aug 18 '13 at 13:15
  • Thanks for that, but again, IT IS NO DATABASE ERROR... The Context connects to the db, it just returns false there for no reason... any exception would be rethrown towards me... – Nefarion Aug 19 '13 at 19:11
  • 16
    I just don't buy all of this new membership tech that MS is forcing down our throats. The Asp.net Membership from the old days was super easy to use out of the box. You could even launch a configuration website from within VS to create users and roles. With this crap I'm spending an hour trying to figure out how to change from the mdf that magically auto generates tables to a real sql server. – The Muffin Man Jan 18 '14 at 23:27
  • For the benefit of searchers, I couldn't stop my project looking at localdb for some reason. The error on update-database -verbose was "Target database is: 'DefaultConnection' (DataSource: (localdb)\mssqllocaldb". This seemed to be the fix. – JsAndDotNet Jan 10 '17 at 22:01
5

The answer is not valid anymore for the 1.0 version that comes with VS2013 on the new mvc5 application. To do this now:

Declare a class like:

public class AppUserStore : UserStore<IdentityUser>
{
    public AppUserStore():base(new MY_IDENTITYDBCONTEXT())
    {

    }
}

And on Startup.Auth.cs change

UserManagerFactory = () => new UserManager<IdentityUser>(new UserStore<IdentityUser>());    

to

UserManagerFactory = () => new UserManager<IdentityUser>(new AppUserStore());

Without this your IdentityDbContext constructor (and OnModelCreating, for example) will not run when creating a User with asp.net identity.

Leo
  • 7,379
  • 6
  • 28
  • 44
2

I had the same problem and struggled a bit since there's not much material in net about ASP.NET Identity yet. After doing a check on the assemblies I found it's actually simple.

Just find the place where your AuthenticationIdentityManager is initialized and use the IdentityStore overload to specify your db context, like this:

IdentityManager = new AuthenticationIdentityManager(new IdentityStore(new Model()));

My model class inherits DbContext. Hope this helps.

Joao de Araujo
  • 1,096
  • 2
  • 15
  • 27
2

RobM has the comprehensive answer and Rob B has the simple answer.

In your scenario, you are setting your base to "MyConnectionString" which in your config file does not exist.

<connectionStrings>
    <add name="MySailorContext" connectionString="Data Source=THOMAS-LAPTOP;Initial Catalog=MySailor;Integrated Security=True;Pooling=False;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
    public MyDbContext() : base("MyConnectionString") { }
}

Whatever name you give your connectionString has to match whatever you have in your DbContext : base

<connectionStrings>
    <add name="MySailorContext" connectionString="Data Source=THOMAS-LAPTOP;Initial Catalog=MySailor;Integrated Security=True;Pooling=False;MultipleActiveResultSets=true" providerName="System.Data.SqlClient"/>
</connectionStrings>

public class MyDbContext : IdentityDbContext<MyUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
{
    public MyDbContext() : base("MySailorContext") { }
}
Terri
  • 354
  • 6
  • 18
  • That is what I do to change on those two part but get error A network-related or instance-specific error occurred while establishing a connection to SQL. – Tony Dong Feb 09 '18 at 22:05
1

If all you need is to change the connection string used by the identity provider, the following is not very elegant but seems to work. Search where the IdentityManager class is instantiated and add the following:

//Leave this untouched:
IdentityManager = new AuthenticationIdentityManager(new IdentityStore());
//...and add this:
((IdentityStore)identityManager.Store).DbContext.Configuration
    .Database.Connection.ConnectionString = "your connection string here";
Konamiman
  • 49,681
  • 17
  • 108
  • 138
  • Just a note on the comment above. You should never put your connection string in the code,as a good practice you should put it into an appConfig file and consume it from there everywhere it's needed. System.Configuration.ConfigurationManager.AppSettings[key]; – Matias Mar 14 '17 at 17:18
1

Since there are alot of changes on this when going to RTM, i have updated the SPA template that uses a WebApi controller for all the identity signin and such. Its a really cool template , if you havent seen it.

I put all my code here: https://github.com/s093294/aspnet-identity-rtm/tree/master

(Do note, its only for inspiration. I only made it work and nothing more. Properly have a bug or two also).

Poul K. Sørensen
  • 16,950
  • 21
  • 126
  • 283
1

Look for the class that inherits from IdentityDbConect eg:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }
    }

Then change the "DefaultConnection" to the name of a connection string identified in your web.config.

Rob Bowman
  • 7,632
  • 22
  • 93
  • 200
  • Not working, do we need to change more place, change web.config and applicationDbContext not enough for me. – Tony Dong Feb 09 '18 at 22:07