1

I am working on creating a MVC4 multi-tenant site that uses seperate DBs for each tenant and have been trying to get the membership piece to work for each tenant without any luck.

For some reason connectionStringField is always null no matter what I do. Any ideas why this could happen?

public class CodeFirstMembershipProvider : MembershipProvider
    {    
      public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)  
      { 
          base.Initialize(name, config);  

          // hard coded for testing  
          string connectionString = @"server=localhost;database=masterdb;uid=master;pwd=password";

          // Set private property of Membership provider.  
          FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);  
          if(connectionStringField != null)
            connectionStringField.SetValue(this, connectionString);  
      }
}
Todd
  • 1,780
  • 7
  • 32
  • 54
  • I need to do the same but I thought the provider was configured for the whole application so looked elsewhere – GraemeMiller Oct 16 '12 at 23:32
  • its setup in the web.config but changed dynamically from above. People say they have gotten this to work but I can't for some reason. – Todd Oct 17 '12 at 00:00
  • I don't know if this would work for your application, but it is possible to have multiple providers, each connecting to a different DB, like the last answer to this question: https://stackoverflow.com/questions/26840688/how-to-change-database-for-asp-net-membership-with-every-page-request – John Gilmer Feb 22 '19 at 11:35

1 Answers1

6

You can't make this work. Even if you could figure out how to get the reflection to function the way you want. It will lead to instability and unexpected results.

The reason is that the Membership Provider is a global static, single instance that is used across all concurrent users. That means if you change the connection string for one user, it changes it for all of them. Worse, you might change it for one, then have a context switch to another user and they might overwrite that change, then come back and the app isn't in a state that it thinks it's in.

The built-in Membership system is not designed to have it's internal data changed while it is running. It's designed to use a single database for multiple applications.

If you insist on using separate databases for each tenant, then you will have to implement your own authentication system, because Membership simply will not work in the situation you want it to. It may appear to work at first, but as your site gains more concurrent users, it's a ticking time bomb waiting to blow up in your face.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • Thanks for the nice explanation regarding the global static instance. I didn't realize this. Looks like i'll be rolling my own. – Todd Oct 17 '12 at 02:13