Multiple ASP.NET Configuration Files - asp.net

I have found a number of pieces of information on having multiple ASP.NET configuration files for a web deployment. However, I am still unsure if I can accomplish what I want to accomplish.
Basically, the website I am working on can be deployed to three different sites. Depending on the site that it is deployed to, the configuration settings need to be changed. What I would like to do is have configuration files for each possible configuration (full web.config files) and then be able to tell a deployment build which config file to use for a particular deployment (I can edit this manually if necessary).
Is there something as simple as pointing to a different .config file, or do I need to do something more sophisticated?
EDIT: One particular concern that I have is that I also need settings in system.net for mail settings, etc. So, I'm not looking to only override the appSettings.
Thanks

Any configuration section - such as <smtp> - can be "externalized", e.g. stored in an external file.
Other than the file= statement on <appSettings> (which is available only for app settings :-() it's not a "additional" setting - you just point your config system to an external file.
So you could have this in your app.config/web.config:
<system.net>
<mailSettings>
<smtp configSource="smtp.test.config" />
</mailSettings>
</system.net>
and this in your smtp.test.config:
<?xml version="1.0" encoding="utf-8" ?>
<smtp>
<network host="smtp.test.com" port="244" userName="test" password="secret" />
<specifiedPickupDirectory pickupDirectoryLocation="C:\temp\mails"/>
</smtp>
This works as of .NET 2.0 (maybe even 1.x), and it works for every configuration section - but not for configuration section groups like <system.web>.
Of course, you can now create additional config files, like smtp.staging.config and so forth, and now your problem has been reduced to replacing a single line in your web.config.
You can do this using an installation script, a XML preprocessor, or even by human intervention.
It doesn't completely solve the problem as .NET 4 and the web.config transformations hopefully will, but it's a step and a bit of help.

On your main web.config add the following attribute to appSettings
<appSettings file="Web.site1.config">
Then, asp.net will see both files as one. You can edit web.config in order to include a different external file, depending on the Site.

You can do this in .Net Framework 4. ScottGu shows a quick demo of it in his recent talk in Sweden. In his example he has staging, production etc. with each file having (potentially) different content.

Related

Private web.config for each developer

Consider a group of developers working on an ASP.net web application. Each developer would like to have a private version of the web.config.
By "private" I mean that a developer can freely change the file to suit their dev/test needs at any given moment, without it affecting other team members and without ending up in source control.
How can one go about achieving this with Visual Studio 2015?
My closest solution so far is to have a "private" Solution Configuration with a matching Web.config Transformation file ("web.private.config") that's excluded from source control.
But this is not a satisfactory solution because:
a. The transformation is not run automatically when debugging (with F5). The developers need to remember to run it manually.
b. The result of the transformation ends up in the main "web.config" file which is, naturally, included in source control.
We had a very similar problem but only needed personalized versions of the <appSettings> section in Web.config.
In this situation the inclusion of an external file through configSource turned out to be problematic, as this attribute completely replaces the <appSettings>-node. So there remains no way to keep global key/values AND personal key/values for all developers. The whole section is completely replaced by the included private file.
What we need is both global and private <appSettings>. The solution we found was the file attribute. It allows to merge Web.config settings with settings from an additional file.
We ended up with a construct like this one:
<!-- Web.config with global appSettings) -->
...
<appSettings file="Web.PERSONAL.config">
<add key="BaseUrl" value="https://projectname.dev.local" />
...
</appSettings>
...
­
<!-- Web.PERSONAL.config with personal appSettings -->
<?xml version="1.0" encoding="utf-8"?>
<appSettings >
<add key="EmailSmtpUser" value="my.name#my.domain.com" />
<add key="EmailSmtpPwd" value="***" />
</appSettings >
If you put identical keys in both files, the Web.PERSONAL.config version will overwrite the Web.config version.
The file Web.PERSONAL.config must be excluded from Git through .gitignore .
Keep in mind:
While configSource works for ALL nodes in Web.config, the file attribute is restricted to <appSettings>.
Have web.config include an external file (via configSource) and add that file to .gitignore
The correct answer is to host your local development site in a separate location from your Visual Studio solution. You can then use publish profiles to publish changes to that location and web.config transforms to maintain a separate local config for each developer. Each developer would use a different publish profile which transforms the web.config with their own transform and deploys the transformed web.config to the publish location. You can then attach a debugger to the published site using Visual Studio's Debug > Attach To Process option.
I think there is a lot of value in standardising dev environments so that one can just download the solution and run it.
Custom, long term/permanent, developer specific configs will sooner or later lead to a subtle bug that will be tricky to find.
My solution to your problem would be to find out the reason(s) why permanent individual configs are needed and have a look if these environment specific differences can be eliminated.

Set up IIS to use non-standard .config file

Is there a way to tell IIS to read configurations from a different file than web.config?
Why would anyone do this?
Convenience. When working with static resources like an .aspx, or .js, or an MVC view file, it is often sufficient to hit Refresh in the browser to see the effect of that change.
Also, more specific to our scenario is that we re-use some of our code-base in different flavors of the web site, their differences being defined in their respective .config files, and each of these sites run locally on our development clients.
Getting the change to a different location than the one you are actually working in is somewhat time-consuming: A Publish operation will properly compile and copy the entire web application to the target location, copying the individually changed file manually is often... fiddly.
So what I would like for to be possible is this:
I work on my project in c:\workbench\FlavMaster3000. In this folder I create the various flavors of web.config files:
web.apple.config
web.banana.config
web.cherry.config
I create sites in IIS that represents each flavour and set their directory to the same as above.
https://local-apple/
https://local-banana/
https://local-cherry/
And I would like for IIS to read each site's configurations from the respective flavor of .config.
Is this at all possible, or am I a dreamer with a hopeless dream?
-S
You can put your specific configuration in external file(s) and link those files in your web.config file as shown below. However downside is way web.config is watched for any changes in it and gets applied immediately when you save web.config, these external files will not be monitored and you will require to manually restart app pool.
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<appSettings configSource="Myconfigs/myappSettings.config"/>
<connectionStrings configSource="Myconfigs/myconnections.config"/>
<system.web>
<pages configSource="Myconfigs/mypages.config"/>
<profile configSource="Myconfigs/myprofile.config"/>
<httpHandlers configSource="Myconfigs/myhttpHandlers.config"/>
<httpModules configSource="Myconfigs/myhttpModules.config"/>
</system.web>
</configuration>

Can included sections in Web.config be encrypted

I have an ASP.NET MVC5 website in development which I will shortly need to deploy to an IIS8 webserver. I'm trying to get the security model for the web.config file right, and in particular I want to:
Prevent secrets in the web.config file being exposed in my source control system
Protect the deployed web.config from prying eyes (I don't own the server).
From searching on SO and other sites I can see that there are specific tools/techniques to address each scenario:
'Included' sections in web.config that do not get saved to the SCCS.
Encrypted web.config files. Or encrypted sections of the file to be more precise.
I'm fine with both of those, but I can not for the life of me see how to combine the two techniques to solve both problems simultaneously. Is it possible to encrypt an external section? Is this even the right approach given that many of the answers are several years old now and address older versions of ASP.NET/MVC.
I can't be the first do want to do this so I'm sure I'm missing something obvious.
It has been suggested that this might already be answered here, however that question is about encrypting sections in the main web.config file, and I am asking about encrypting external sections. By that I mean sections that are 'included' using the configSource XML attribute.
It's probably bad form to answer ones own question, but I had a flash of inspiration and after a couple of hours of experimentation I have it working how I want.
The bit I had got all wrong was that I was trying to encrypt the external files. It does not work like that. Here's how it does work, at least, this is how it works for me on an IIS8.5 and ASP.NET v4.0.30319 server.
ConnectionStrings
Create the connectionStrings section in a separate file, e.g. Web.connectionStrings.config:
<?xml version="1.0"?>
<connectionStrings>
<add name="MyConnection" connectionString="{your connection string here}"
providerName="System.Data.SqlClient" />
</connectionStrings>
Ref this file from web.config:
<connectionStrings configSource="Web.connectionStrings.config" />
Make sure the external file is not under source code control so it does not get uploaded to your SCCS.
Deploy BOTH files, either as part of your deployment process or deploy the secure file manually if you're really paranoid.
Encrypt the connectionStrings section of the web.config normally, using the aspnet_regiis.exe command mentioned in the article mentioned by Afzaal. This process actually encrypts the contents of the Web.connectionStrings.config file and leaves the web.config file unchanged. You need to leave the external file in place but as it is now encrypted this is quite safe.
appSettings
Create your security-critical settings in a separate file, e.g. Web.appSettings.config.
<?xml version="1.0"?>
<appSettings>
<add key="wc1" value="web.app.config1" />
<add key="wc2" value="web.app.config2" />
</appSettings>
Ref this file from web.config:
<appSettings file="Web.App.config">
{other non-secure appSettings}
</appSettings>
Again, ensure the secure file is not under source control, and deploy both files to the production server.
Encrypt the appSettings section of the web.config file.
Unlike the connectionStrings section, this does not alter the external file at all. Instead, settings from both web.config and the external file are merged (external file takes precedence if duplicate keys are encountered) and are stored in an encrypted form in web.config.
At this point you can remove the Web.appSettings.config file as its contents are now incorporated into the main file.
Points to note:
If you introduce another Web.appSettings.config file at a later time, and restart the site, the contents of that file will override the encrypted settings in web.config. This may or may not be useful. When you remove the file and restart the site, the settings revert to the encrypted ones again.
If you decrypt the appSettings section, ALL the current settings are written back into the main web.config file, including those that originally came from the external file. You'll need to remember to remove them if you're just changing a setting and then re-encrypting the file again.

how can i use same web.config file for two web appliction?

I have two web application. Their folder hierarchy in server is like that.
first one is : .../firstapplitaion
second is : .../firstapplication/secondapplication/Default.aspx
At first can i run them with just firstapplication's web.config file? secondapplication's web config hasnt any special things.
Thanks for your helps..
One way would be to have a section in your web.config files point to an appropriate file, like this
<configuration>
<appSettings file="C:\MyCommonFolder\MyCommonAppSettings.config">
</appSettings>
</configuration>
Hope that helps
If the second app's web.config file is the same why bother to even run them as seperate apps? Why not just make them one app that uses the same web.config? Or were you trying to split them into seperate app pools?
What I have done in a similar situation was to have each site contain it's own seperate web.config but to move all of the shared pieces into my Machine.config. For me it's locatd in the C:\WINDOWS\Microsoft.NET\Framework\vX.X.XXX\Config folder (I would suggest backig it up first). Because of the way the config files work you can put settings in your machine.config and your websites will inherit these settigs. So put any shared settings there, with very unique names, and you should be set.

Is web.config or app.config cached in memory

if it is cached, what happens if I use multiple web.config in multi-level folders
They all get cached.
Configuration is read once, at startup. With web.config, IIS watches for file changes and restarts the application.
OK, so ya'll are missing a KEY feature in the Web.Config file's area.
Yes, web.config is cached and changing contents of the file will restart your web app. And, all your connected users will not be happy, too, because they'll need to "reconnect" a-new, possibly losing desired information.
So, use an EXTERNAL custom file for your AppSettings, as follows:
<appSettings configSource="MyCustom_AppSettings.config"/>
Then, in the file MyCustom_AppSettings.config file, you have your settings, as such this example has:
<appSettings>
<!-- AppSecurity Settings -->
<add key="AppStatus_Active" value="Active"/>
<!-- Application Info Settings -->
<add key="AppID" value="25"/>
<add key="AppName" value="MyCoolApp"/>
<add key="AppVersion" value="20120307_162344"/>
</appSettings>
Now, if you need to add, change, or remove an AppSetting, when you change it in this file the change is nearly instant in your web-app BUT (and here's the BEST part), your app DOES NOT RESTART!
Everything stays kosher except those settings you've added/modified/removed in the external .config file.
And, yes, the same thing can done for the section as follows:
<connectionStrings configSource="MyCustomApp_ConnectionStrings.config"/>
and the file MyCustomApp_ConnectionStrings.config has all the connection strings you need. Change a connection string in the external .config file and it starts getting used right away and with no web-app restart.
The configSource setting(s) are great when you need to deploy to development, testing, and production on different boxes and need settings pertinent to that given box/environment.
So, now ya know (something that's been around for 7+ years).
It's That Simple. Really.
KC
Web.config (excluding external config files) is read when the application loads. Some config settings have a cascading behavior. For example, the system.web/authorization section can be overridden by configs at deeper levels.
ASP.NET monitors the web.config for changes. When it changes, the web application is forced to restart. Moral is that web.config settings are cached for the life of the application.

Resources