Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MembershipProvider change connection string in code

I am trying to implement Asp.net Forms Authentication in my site. Usually, you provide the name of your DB connection string in your web.config. However, as our database setup is a little more complicated, I was looking for a way to manually provide the MembershipProvider the connection string in code.

Thanks!

like image 490
TheCatWhisperer Avatar asked Jun 03 '13 19:06

TheCatWhisperer


2 Answers

You don't have to use a connectionStringName for SqlMembershipProvider, instead you can supply the connection string directly. I.e. instead of:

<membership defaultProvider="SqlProvider" ...>
  <providers>
    <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
         connectionStringName="MyConnectionStringName" 
         .../>
  </providers>
</membership>

You can specify the connection string directly as:

<membership defaultProvider="SqlProvider" ...>
  <providers>
    <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider"
         connectionString="data source=... " 
         .../>
  </providers>
</membership>

Therefore you could also derive a custom provider from SqlMembershipProvider, and build the connection string dynamically as follows:

public class MySqlMembershipProvider : SqlMembershipProvider
{
    public override void Initialize(string name, NameValueCollection config)
    {
        config["connectionString"] = BuildMyCustomConnectionString();
        base.Initialize(name, config);
    }
}
like image 113
Joe Avatar answered Sep 28 '22 04:09

Joe


I came across this needing to do the same thing, set the connection string via code and not in the web.config, although I needed to change more than the name, I needed the actual value to be dynamically generated. If you want to change the actual connection string to be generated from code you can do the following:

web.config

...
  <connectionStrings>
    <add name="ConnectionPlaceHolder" connectionString="This is a place holder"/>
  </connectionStrings>
...
    <roleManager defaultProvider="SqlRoleProvider" enabled="true">
      <providers>
        <clear/>
        <add name="SqlRoleProvider" type="MyClassLibraries.Web.Security.MyCustomSqlRoleProvider" connectionStringName="ConnectionPlaceHolder" applicationName="MyApplicationName"/>
      </providers>
    </roleManager>

Provider Class

    public class MySqlRoleProvider : SqlRoleProvider
    {
        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            try
            {
                config["connectionStringName"] = "ConnectionPlaceHolder";
                base.Initialize(name, config);

                FieldInfo connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
                connectionStringField.SetValue(this, ApplicationConfiguration.RetrieveApplicationConfigurationValue(myConnectionString));
            }
            catch (Exception ex)
            {
                CurrentOperation.RaiseException(ex);
                throw ex;
            }
        }

        private string myConnectionString()
        {
          return "Server=MyServer;database=MyDB;uid=aspnetDBUser;pwd=myPassword"
        }
    }

When you call base.Initialize() the .NET class requires there be a name specified in the web.config which is why you have to put something, so I just used a placeholder since I knew I would be overriding it in the code.

Our team did this because we needed to dynamically build connection strings based on different environments and didn't want to have to worry about having multiple web.configs floating around.

like image 44
Flea Avatar answered Sep 28 '22 02:09

Flea