i am looking for a easy & elegant way to change my appsettings in web.config based on the different environment and i have (dev/qa/test/stage/prod) and i am manually changing the appsettings and its very tedious and time consuming and i have about dozens of settings.... what is the best approach for this kinda situation? i know one solution using Environment variables but wants to hear the best practice?
8 Answers
I prefer using externalized sections of web.config, like so:
<appSettings configSource="appsettings.config" />
then appsettings.config looks like so:
<appSettings>
<add key ...>
</appSettings>
This allows me to save app settings in separate file that doesn't change, while still allowing me to edit main web.conifig for actual configuration portions. You can do same thing to other sections - connection strings, system.net (for email config) etc.
I actually don't think VS2010 way is very good, since it requires re-build just to change config. With my way, it's usable without VS at all, so i can easily modify all my environments by hand.
1 Comment
If possible upgrade your app to asp.net 4.
This version has a web.config transforms feature which is intended to solve exactly this problem:
8 Comments
I will typically do the following:
- Include multiple versions of each config value, one for each environment
- Make a small class for reading my app settings. In this class, create a function that detects the current environment.
- For each setting, create an accessor property that has a switch which uses the environment detection function to determine which value to return.
It takes a bit of initial setup, but once configured, it provides an easy and worry-free method of getting to your config values.
2 Comments
web.config-dev, web.config-qa, web.config-prod, and i have function which returns me in which environment iam and assume that i am in qa box so what/how do i read web.config-qa can you show me some sample code if you have already done.If you use VS2010 (NET tools version 4) then you can do web config transformations and build a deployment package to deploy to staging, production etc. It does not matter what your target version of asp.net is. Then deploy the package and tada you'll have the custom configuration file installed on your target. No need for the run-time to figure it out. I do this all the time using 3.5 as my target version of .NET using MSBuild 4, which VS2010 uses. My development environment has different application settings than my production and staging environments.
1 Comment
Ultimately, I recommend making use of the Web.config Transformation feature in Visual Studio 2010, if possible.
If VS2010 is not an option or you do not wish to use the config transformation feature, take a look at this solution I came up with a while ago. It uses a combination of a batch file and a NANT script to generate config files from a single template and one or more substitution files. It isn't nearly as powerful as the Web.config transformation tool, but it's a pretty effective alternative.
http://blog.nathan-taylor.net/2009/10/webconfig-build-manager.html
Comments
Prior to VS2010, we actually named ours web.prod.config, web.qa.config, etc.. I guess we had some great forsight.
In any event, under VS2008 we had a copy command which executed as part of the build step would copy the appropriate config file based on the configuration we were building. Our regular web.config pointed to dev and we used TFS to deploy to the other environments.
Comments
I know you've already accepted an answer, but I use the method of having different config files according to the different environments, and named as such.
For example, I have appsettings.config.debug, appsettings.config.deploy, web.config.debug, web.config.deploy.
Then, I have a pre-build script that runs a batch file that copies the config file related to my current configuration setting into a file without the Configuration setting suffix. It only does this if the files are different using FC.
My pre-build event command-line code is:
"$(ProjectDir)copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config"
and
"$(ProjectDir)copyifnewer.bat" "$(ProjectDir)appsettings.config.$(ConfigurationName)" "$(ProjectDir)appsettings.config"
And my copyifnewer.bat file is:
echo Config Maintenance
echo Today's date of %date:~-4,4%\%date:~-10,2%\%date:~-7,2%
rem echo Comparing two files: %1 with %2
echo .
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2
if %ERRORLEVEL%==0 GOTO NoCopy
echo These files are NOT the same. Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo These files are the same. Nothing copied.
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.
echo .
This works great for me. Hope this helps someone.
Thanks, Scott