Switch connection string conditionally based on the domain
Hi,
Is there a way to switch or call different connection strings based on the condition in Umbraco 7.
Practically I have development and production environments with each own databases. What I would need is to have two connection strings in web.config and application would pick the right one based on the domain.
Different connection strings = different cache, so you need to rebuild cache for each connection string.
I would suggest to use 2 instances, or one Umbraco with 2 trees inside, but we don't recommend to use one instance and 2 connection strings definitely.
The connection string name is a constant in the core, so you can't switch connection strings. I agree you want to sites in the same instance or two different sites.
My situation is that I have two instances on the servers (staging and production environments, beside development on my PC) and there's automated tool that promotes content from one environment into the other.
With the current setup by having a single connection string in web.config before promoting site into the production I would need to manually update it to point to the production database. Of course after promotion I would set it back to point to staging database. In order to avoid any discrepancy later in future promotions (which might be done by someone else beside myself, who might forget to modify connection strings during promotion) I was trying to find a solution that would automatically select connections strings from web.config based on the host.
In other applications (not Umbraco) I have simple code as:
var connStringName = "";
var serverName = Request.ServerVariables["SERVER_NAME"];
if (serverName .Contains("stage"))
connStringName = "dbStage";
else
connStringName = "dbProduction";
return connStringName;
...which works just fine. Therefore I was wondering if there's a way to override the default "umbracoDbDSN" connection string.
This limitation is really bad in large dev-ops. Where we have no production access, and asking a server guy to change connection string, flush the cache, and stop and start the site, and then it still might not work, is a constant headache. I've launched 8+ sites with constant maintenance, with 3 different environments (dev, QA, prod) each with own database. This is how corporate dev-ops work. Everywhere.
We cannot use uSync because of directory permissions. ie, we cannot have the root level uSync write to separate server db, and we cannot allow plugin, access to root directory. Plus, experience says, plugins do not migrate well either!!!
We cannot pay for a paid syncing tool, we cannot go to cloud.
Someone please write a fool-proof deployment guide within these limits!
I would think it is a pretty common requirememt for local db server in dev and different in production. As you say you have the difficulty of syncing the two databases but i would look at this
Provided these are the same website with a configsource for your connection string key you could have different files in each of your environments containing the correct details
What I would like to have is to have identical code (in staging and production environment) + two databases (in staging and production environment) where code would know how to switch between databases based on the host. My issue is not to write the code to do that, but to "hijack" the part where umbraco core picks the connection string name.
I'm using compiled version of Umbraco, not the source code.
I've been digging a bit into the source code of Umbraco and I found that connection string name umbracoDbDSN is declared in Umbraco.Core > Configuration > GlobalSettings.cs as...
public const string UmbracoConnectionName = "umbracoDbDSN";
...which "consumed" here... (the same .cs file)
/// <summary>
/// Gets the database connection string
/// </summary>
/// <value>The database connection string.</value>
[Obsolete("Use System.Configuration.ConfigurationManager.ConnectionStrings[\"umbracoDbDSN\"] instead")]
public static string DbDsn
{
get
{
var settings = ConfigurationManager.ConnectionStrings[UmbracoConnectionName];
var connectionString = string.Empty;
if (settings != null)
{
connectionString = settings.ConnectionString;
// The SqlCe connectionString is formatted slightly differently, so we need to update it
if (settings.ProviderName.Contains("SqlServerCe"))
connectionString = string.Format("datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;{0}", connectionString);
}
return connectionString;
}
set
{
if (DbDsn != value)
{
if (value.ToLower().Contains("SQLCE4Umbraco.SqlCEHelper".ToLower()))
{
ApplicationContext.Current.DatabaseContext.ConfigureEmbeddedDatabaseConnection();
}
else
{
ApplicationContext.Current.DatabaseContext.ConfigureDatabaseConnection(value);
}
}
}
}
I'm not sure this option is the best in my scenario. For me staging and production environments are on the web servers, where only in staging environment I can access the files in order to modify the web.config. Therefore if I wish to have production connection string in production I need to modify web.config still in staging environment. After I push the content into the production (by dedicated script) I could basically reverse the change in the web. config in staging environment in order so connection string will point back to the staging database.
Sorry, I'm not entirely sure what was your question, but I have access to the files on the staging environment, but not direct access to files in production. I can only push all files at once from staging into production. If I need a change in production I need to make a change in staging before and then push it through (by change I mean changes that are not done through application logic).
Switch connection string conditionally based on the domain
Hi,
Is there a way to switch or call different connection strings based on the condition in Umbraco 7.
Practically I have development and production environments with each own databases. What I would need is to have two connection strings in web.config and application would pick the right one based on the domain.
Thanks and regards, Srecko
Hi Srecko,
Different connection strings = different cache, so you need to rebuild cache for each connection string.
I would suggest to use 2 instances, or one Umbraco with 2 trees inside, but we don't recommend to use one instance and 2 connection strings definitely.
Thanks,
Alex
The connection string name is a constant in the core, so you can't switch connection strings. I agree you want to sites in the same instance or two different sites.
Thanks David!
Thank you both Alex and David for your inputs.
My situation is that I have two instances on the servers (staging and production environments, beside development on my PC) and there's automated tool that promotes content from one environment into the other.
With the current setup by having a single connection string in web.config before promoting site into the production I would need to manually update it to point to the production database. Of course after promotion I would set it back to point to staging database. In order to avoid any discrepancy later in future promotions (which might be done by someone else beside myself, who might forget to modify connection strings during promotion) I was trying to find a solution that would automatically select connections strings from web.config based on the host.
In other applications (not Umbraco) I have simple code as:
...which works just fine. Therefore I was wondering if there's a way to override the default "umbracoDbDSN" connection string.
Thanks, Srecko
Resurecting this, if I may.
This limitation is really bad in large dev-ops. Where we have no production access, and asking a server guy to change connection string, flush the cache, and stop and start the site, and then it still might not work, is a constant headache. I've launched 8+ sites with constant maintenance, with 3 different environments (dev, QA, prod) each with own database. This is how corporate dev-ops work. Everywhere.
We cannot use uSync because of directory permissions. ie, we cannot have the root level uSync write to separate server db, and we cannot allow plugin, access to root directory. Plus, experience says, plugins do not migrate well either!!!
We cannot pay for a paid syncing tool, we cannot go to cloud. Someone please write a fool-proof deployment guide within these limits!
I would think it is a pretty common requirememt for local db server in dev and different in production. As you say you have the difficulty of syncing the two databases but i would look at this
http://stackoverflow.com/questions/6940004/asp-net-web-config-configsource-vs-file-attributes
Provided these are the same website with a configsource for your connection string key you could have different files in each of your environments containing the correct details
Hi Ian,
We didn't understand each other.
If you have local and dev evnironment you can you uSync and other stuff for sync database changes, but issue is with one site - few databases.
Thanks,
Alex
Hi,
What I would like to have is to have identical code (in staging and production environment) + two databases (in staging and production environment) where code would know how to switch between databases based on the host. My issue is not to write the code to do that, but to "hijack" the part where umbraco core picks the connection string name.
I'm using compiled version of Umbraco, not the source code.
I've been digging a bit into the source code of Umbraco and I found that connection string name umbracoDbDSN is declared in Umbraco.Core > Configuration > GlobalSettings.cs as...
...which "consumed" here... (the same .cs file)
Thank you for any idea.
Srecko
Hi Srecko,
You don't need code for that, just use config transformations - http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/web-config-transformations
Hi Alex,
I'm not sure this option is the best in my scenario. For me staging and production environments are on the web servers, where only in staging environment I can access the files in order to modify the web.config. Therefore if I wish to have production connection string in production I need to modify web.config still in staging environment. After I push the content into the production (by dedicated script) I could basically reverse the change in the web. config in staging environment in order so connection string will point back to the staging database.
Kind regards, Srecko
Interesting, so you haven't access to deploy to live?
Sorry, I'm not entirely sure what was your question, but I have access to the files on the staging environment, but not direct access to files in production. I can only push all files at once from staging into production. If I need a change in production I need to make a change in staging before and then push it through (by change I mean changes that are not done through application logic).
is working on a reply...