Introduction
After finding this simple solution hidden in the patchwork of documentation, I decided to write a brief tour of the basics of the .NET configuration namespaces, as well as share this tip.
The ConfigurationManager
namespace, introduced with .NET 2.0, cannot be used to save connections strings. ConfigurationManager.ConnectionStrings.Add()
throws an error and System.Configuration.ConfigurationManager
does not allow saving to app.config.
While the simplest answer may be to write XML, the .NET 1.1 configuration API System.Configuration.ConnectionStringSettingsCollection
supports modification and saving. The last part of this tip is refreshing the 2.0 ConfigurationManager
after modifying the config file.
The Basics
The Configuration APIs are confusing, rather than complex. The combination of poorly chosen names and bloated functionality can be navigated safely with a quick guided tour.
Three Configuration Files
There are three filenames: app.config, YOUR_APPLICATION.exe.config, YOUR_APPLICATION.vshost.exe.config.
Copy to Output Directory
App.config is the source file which is copied and renamed when a project is built. The IDE overwrites YOUR_APPLICATION.exe.config with app.config depending on the setting of the “Copy to Output Directory” property. Solution Explorer > app.config > Right-click Properties > Copy to Output Directory. Note that F4 shows the XML document properties if the focus is on the code pane, rather than the solution pane.
Each Section is Different
App.config is divided into sections. Each section has its own handler that defines how to read and write the section. Predefined sections that predate .NET 2.0 have predefined/hardwired handlers. For example, appSettings
can be managed using System.Configuration.ConfigurationSection.AppSettingsSection
.
Two Similar Sections
There are two sections with similar names: appSettings
and applicationSettings
. I find it impossible to remember which is which. (The longer name is newer, and is the section added by the IDE starting with .NET 2.0. Solution Explorer > Application Properties > Settings.)
Two Similar Namespaces
There are two similar namespaces: System.Configuration.Configuration
and System.Configuration.ConfigurationManager
. The longer one (“ConfigurationManager
”) is newer. It was introduced in .NET 2.0. While it has nice features like type safety and code generation for each defined setting, it does not support saving applicationSettings
or connectionStrings
to app.config. The applicationSettings
section is read-only.
The applicationSettings
section introduced with .NET 2.0 is managed by the System.Configuration.ClientSettingsSection
class. Many developers have been stymied and annoyed that the applicationSettings
section in app.config is read-only. While the rationale for not storing user preferences in app.config is sound, the inability to persist settings for valid reasons (e.g., installation or configuration) is unnecessarily limiting.
The connectionStrings Section
Some sections, such as the connectionStrings
section, can be managed by both namespaces.
For connection strings, the predefined handler is System.Configuration.ConnectionStringSettingsCollection
. .NET 2.0 introduced System.Configuration.ConfigurationManager.ConnectionStrings
.
Both frameworks can read connection strings from app.config. System.Configuration.ConnectionStringSettingsCollection
allows additions.
System.Configuration.ConfigurationManager.ConnectionStrings
is a read-only collection that implements Add()
, but Add()
throws run-time errors.
Using the Code
Saving connection strings is simple when you use the old configuration namespace framework.
public static void AddAndSaveOneConnectionStringSettings(
System.Configuration.Configuration configuration,
System.Configuration.ConnectionStringSettings connectionStringSettings)
{
ConnectionStringsSection connectionStringsSection = configuration.ConnectionStrings;
connectionStringsSection.ConnectionStrings.Add(connectionStringSettings);
configuration.Save(ConfigurationSaveMode.Minimal);
ConfigurationManager.RefreshSection("connectionStrings");
}
Points of Interest
- The
System.Configuration.Configuration
namespace supports reading from config files other than app.config. See ConfigurationManager.OpenExeConfiguration
and ConfigurationManager.OpenMappedExeConfiguration
. - You can move your connection strings to a separate file (much like an
include
file) by adding a line to your app.config:
="1.0"="utf-8"
<configuration>
<connectionStrings configSource="connectionstrings.config"/>
</configuration>
Where connectionstrings.config is the name of the separate file, but could be any name. Note, this file has to be in the same folder (*or deeper) as the config file. This trick can be used to define different NTFS based file-permissions on the connections strings file from the app.config file.
- Even when connection strings are in a separate file,
System.Configuration.Configuration.Save()
writes to the correct file.
History
- 10/15/2010: Initial version
- 1/29/2011: Added complete working example project for C# 2.0 (and above) x86