Changing Membership, Profile and Role provider connection string based on environment

by 14. August 2010 00:59

You’re probably no stranger to having to target different environments for your project, e.g. development, qa, staging and production. Often your application relies on a configuration file, web.config for ASP.NET applications, and in this file you will usually have one or more connection strings, targeting a specific server based on the environment. There are several ways to solve this problem, e.g. by using nANT or pre-build events in Visual Studioand indeed I would recommend either of these approaches over the one I’m going to describe below.

However, what do you do if you are deploying your web-application to a deployment server, and that server is then responsible for deploying to two or more environments, e.g. staging and production, and you have now way to tell the server to distinguish between the different environments. In other words, you are stuck with one web.config file. This is not necessarily a problem, unless you are using the membership provider which in its configuration looks something like this:

<add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="SqlServices" applicationName="MyApplication" />

Notice the connectionStringName property. Turns out solving this is pretty straightforward, and Brendan Caffrey over at devspade.com posted an excellent article on how to do it: Using dynamic connection strings with the Asp.Net Sql Membership Provider

However, he only posted the solution for the Membership provider. What if you’re using the Role and profile provider as well? Luckily, the solution is just as simple. I won’t go into details, but just point to Brendan’s article, but here’s the entire source code.

First the actual source code:

using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Reflection;using System.Text;using System.Web;using System.Web.Configuration;using System.Web.Profile;using System.Web.Security;namespace YourNameSpace
{
public class CustomMembershipProvider : SqlMembershipProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);// Update the private connection string field in the base class.
string connectionString = //DetermineYourConenctionString();
// Set private property of Membership provider.
var connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
}
}
public class CustomProfileProvider : SqlProfileProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);// Update the private connection string field in the base class.
string connectionString = //DetermineYourConenctionString();
// Set private property of Membership provider.
var connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
}
}
public class CustomRoleProvider : SqlRoleProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);// Update the private connection string field in the base class.
string connectionString = //DetermineYourConenctionString();
// Set private property of Membership provider.
var connectionStringField = GetType().BaseType.GetField("_sqlConnectionString", BindingFlags.Instance | BindingFlags.NonPublic);
connectionStringField.SetValue(this, connectionString);
}
}
}

And then the web.config:

<membership defaultProvider="CustomMembershipProvider">
<providers>
<clear/>
<add name="CustomMembershipProvider" type="YourNameSpace.CustomMembershipProvider, YourNameSpace" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
</providers>
</membership>
<profile defaultProvider="CustomProfileProvider">
<providers>
<clear/>
<add name="CustomProfileProvider" type="YourNameSpace.CustomProfileProvider, YourNameSpace" connectionStringName="ApplicationServices" applicationName="/"/>
</providers>
</profile>
<roleManager enabled="true" defaultProvider="CustomRoleProvider">
<providers>
<clear />
<add connectionStringName="ApplicationServices" applicationName="/" name="CustomRoleProvider" type="YourNameSpace.CustomRoleProvider, YourNameSpace" />
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>

Have fun!

Tags: , , , ,

ASP.NET

blog comments powered by Disqus