3

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 8

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

this is more about separating installation-specific settings from settings common for all installations
2

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 am using VS2010 but our prod servers are still 3.5 so i have to target 3.5 framework.
hmm if you need to roll your own solution then (and this is a long shot) you might be able to pull the web.config transform feature out of the NuGet project: haacked.com/archive/2010/11/19/nuget-transformation.aspx
@rtpHarry, @Chicagoland: You can still use web.config transformations while targetting .NET 3.5. The functionality requires only that you are using VS2010.
The feature is really annoying to use, are there any alternatives to the web.config transforms in VS2010?
@Nathan I didn't know that, will have to check it out, thanks
|
1

I will typically do the following:

  1. Include multiple versions of each config value, one for each environment
  2. Make a small class for reading my app settings. In this class, create a function that detects the current environment.
  3. 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

i understand your concept but i have a question, so let says i have 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.
I wouldn't change the .config part of the filename...then it could be downloaded potentially (as .config files are protected)...make it dev.config or prod.config perhaps
1

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

Remember in your project file the target can be 3.5, 2.0, etc... $MSBuildPath = "$($(gp -Path HKLM:\Software\Microsoft\'NET Framework Setup'\NDP\v4\full).InstallPath)MSBuild.exe" .$MSBuildPath $ProjectFile /T:Package /ToolsVersion:4.0 /p:Configuration=Release
1

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

1

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

0

We use Nant to script our builds and deploys.

Nant will copy web.config and app.config templates into the locations that the project files expect them. At the same time Nant replaces tokens with appropriate values for the QA environment.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.