10

I need to switch among 3 different environments when developing my web app - Development, UAT, and Prod. I have different database connections in my configuration files for all 3. I have seen switching these settings done manually by changing all references and then rebuilding the solution, and also done with preprocessor directives. Is there an easy way to do this based on some variable so that the configuration doesn't have to be revised when deploying to a new environment every time?

N30
  • 3,463
  • 4
  • 34
  • 43
Mark Struzinski
  • 32,945
  • 35
  • 107
  • 137

5 Answers5

11

To me it seems that you can benefit from the Visual Studio 2005 Web Deployment Projects.

With that, you can tell it to update/modify sections of your web.config file depending on the build configuration.

Take a look at this blog entry from Scott Gu for a quick overview/sample.

Magnus Johansson
  • 28,010
  • 19
  • 106
  • 164
  • This one offered the least friction and lead time, and I was able to get it up and running rather quickly. Thanks for your help! – Mark Struzinski Sep 26 '08 at 07:56
3

I'm a big fan of using MSBuild, in particular the MSBuild Community Tasks (http://msbuildtasks.tigris.org/) and there is an XSLT task to transform the web.config with the appropriate connection string settings, etc.

I keep these tasks handy:

<Target Name="Configs">
<Xslt RootTag="" Inputs="web.config" Output="Web.$(COMPUTERNAME).config" Xsl="web.config.$(COMPUTERNAME).xslt" Condition="Exists('web.config.$(COMPUTERNAME).xslt')" />

Obviously this isn't 100% what you're after, it's so each dev can have their own web.config.

But there's no reason you couldn't use the above principle to have multiple build configurations which applies the right XSLT.

My XSLT looks like this:

<?xml version="1.0" encoding="utf-8"?>

<!-- Dev -->
<xsl:template match="/configuration/connectionStrings/add[@name='MyConnectionString']/@connectionString">
    <xsl:attribute name="connectionString">Data Source=MyServer;Initial Catalog=MyBD;User ID=user;password=pwd</xsl:attribute>
</xsl:template>
<xsl:template match="node()">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

Aaron Powell
  • 24,927
  • 18
  • 98
  • 150
  • I've been looking into MSBuild and/or NAnt as my next thing to learn, but haven't gotten started yet. I know I need to!! – Mark Struzinski Sep 25 '08 at 12:20
  • My answer links to a series of blog posts that teach one how to automate a build with NAnt. You may find it a useful place to get started. – Gilligan Sep 25 '08 at 12:24
  • I don't have any experience with NAnt, what does it offer over the top of MSBuild? – Aaron Powell Sep 25 '08 at 12:27
  • The differences are minute. Nant has more tasks and is slightly more mature, but MsBuild ships with Visual Studio and is actually used by Visual studio underneath the hood, so it may have a lower cost of entry. – Gilligan Sep 25 '08 at 12:31
  • Hmm might have to have a look into it. I'm fairly familiar with MSBuild (writen a few tasks myself which you can get from my blog). – Aaron Powell Sep 25 '08 at 12:43
  • Also a lot of the tasks that the Jean Paul Boodhoo blog series shows do exist in MSBuild. And if you want to use his idea for versioning databse changes, Google DbDeploy. It is a free tool that merges databse change scripts. – Gilligan Sep 25 '08 at 13:24
2

Scott Hanselman has suggested one way to do this:

http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx

Jonathan Parker
  • 6,705
  • 3
  • 43
  • 54
Whisk
  • 3,287
  • 2
  • 30
  • 30
2

You can always use NAnt + NAnt.Contrib to modify the web.config during the build. NAnt has xmlpeek and xmlpoke tasks which allow you to update xml files.

e.g.

<xmlpoke file="${dist.dir}/Web.config" xpath="/configuration/applicationSettings/MyProj.Web.Properties.Settings/setting[@name = 'MyProj_Web_Service']/value" value="http://${AppServer}/Service.asmx" />

JohannesH
  • 6,430
  • 5
  • 37
  • 71
Jonathan Parker
  • 6,705
  • 3
  • 43
  • 54
1

I have adopted the Jean Paul Boodhoo Method of changing configurations. The general idea is to have one or more TOKENIZED configuration TEMPLATE files instead of the configuration files themselves. Then you have a build script task that replaces the tokens with values from a SINGLE local properties file. This properties file contains all differences in configuration and is unique per working copy.

This system has worked great for me and once initially setup is a breeze to manage environment changes.

Gilligan
  • 1,505
  • 2
  • 15
  • 16