I have two applications one a console application and the other an ASP.NET app. They both need to know the same appSettings and connectionStrings. So ideally I would like to
It seems that's that is the way it is. configSource must be in the same folder or deeper.
You could, although I'm not sure you should, use an NTFS hardlink. [mad grin]
I had quite a struggle with this issue, but I found a good solution for it here: test run with external config
(You can direct the test run to copy files and directories into the test run directory by editing the .testrunconfig file.)
Although why the unit test type project can get config settings from its own app.config, but not be able to load referenced config files like a normal app.config is kind of baffling to me. I'd call it a bug because you would expect a test project app.config to behave the same way that the application's app.config behaves, but it doesn't.
You can load configuration from an arbitrary location, but it won't be available via the static properties of ConfigurationManager:
Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path)
(There is an overload that allows multuple files to be specified, to support default/user-roaming/user-local hierarchy.)
Losing the static properties means all the code needs to be aware of the different configuration.
In the case of connection strings, it is indeed possible to point to a shared file. If the shared file is on a network UNC, it requires administrative privileges on the machine where the app will be hosted.
Solution: In your web.config, use configSource to point to a local config file. Due to .Net restrictions, this must be at or below the level of the root config file. I just point to a file in the app folder itself:
<connectionStrings configSource="ConnectionStrings.config" />
In a shared location that is accessible by the application pool user, add the config file containing shared connection strings. This file must not contain any xml other than the connectionStrings section itself. The shared file, ConnectionStrings.config, looks like this:
<connectionStrings>
<clear/>
<add name="connString1" connectionString="connString1 info goes here"/>
<add name="connString2" connectionString="connString2 info goes here"/>
</connectionStrings>
Now the trick. Create a Windows symbolic link in your app folder pointing to the external, shared config file. You will need admin privileges to do this:
mklink ConnectionStrings.config \\someServer\someShare\someFolder\ConnectionStrings.config
We have just outsmarted .Net. The Configuration system will use the configSource setting to find connection strings in a local file called ConnectionStrings.config. The symbolic link looks like a file to .Net, and the symbolic link resolves to the shared configuration file.
Caveats: Changes to the shared file do not automatically trigger an app restart in .Net. In the case of IIS, the web site or app pool will need to be restarted manually.
Due to the need for administrative privileges to create the symbolic link, this approach may not work for everybody. There are two related alternatives that may work if the shared file is on the same logical drive - hard links and junctions. See this discussion and this discussion for more information.
Visual Studio 2015
If you are having this issue with Web.Config the accepted answer is correct but just to expand since this had me giving myself the face-palm:
When you add a .config file to your project using 'Add As Link' and then set the link's Copy property to 'Copy If Newer' or 'Copy Always', then the physical file will be copied to the /bin folder.
Thus, when you have a config section defined in Web.Config like this:
<section name="mySpecialConfig" type="System.Configuration.AppSettingsSection" requirePermission="false" />
then you must define the related config element like this:
<mySpecialConfig configSource="bin\MySpecialConfig.config">
</mySpecialConfig>
such that the configSource points to the physical bin\MySpecialConfig.config file not to the link Also, note that the path is a relative physical path.
That may seem ridiculously obvious but if you haven't done this before the physical file is not yet in the \bin folder so it may not click right away.
You can use the file
attribute rather than configSource
There's a good article here on it
This allows you to specify a relative path like so
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="..\..\..\..\..\..\ExternalFile.config"></appSettings>
</configuration>
The path is relative to the output directory.
Then in ExternalFile.config you just add the appSettings
section
<appSettings>
<add key="SomeKey" value="alue"/>
</appSettings>