Introduction
This article will demonstrate how to add, delete, and update key value pairs in an App.config file at runtime.
Background
Visual Studio .NET has hinted that more powerful support for modifying App.config files at runtime will come with the release of .NET 2.0. Since I didn't want to wait that long, I'm providing the following class containing four methods that will enable you to modify the App.config (or Web.config, with a few minor changes) at runtime. Some of you may have noticed that accessing the System.Configuration.ConfigurationSettings.AppSettings.Add("key","value")
throws an exception (collection is read-only). To get around this, I've written the methods shown below, in the hopes that this will be useful if you have an application that requires users to add, edit, or delete database connection strings, or other such configuration data at runtime.
Using the code
I'm going to go ahead and tack a disclaimer on this article before we begin. Modifying a configuration file at runtime can cause some nasty, unexpected behavior inside your application if it's not managed properly. I'm only giving out the code that will show you how to do it-- please adhere to your own good judgment when determining what key value pairs you will be editing!
Adding New Key-Value Pairs
The following method demonstrates how to add a key and a value to your configuration. It loads the App.config as an XML document, adds the key name and value to the appSettings
node, and saves the document in two places. It will use the helper method KeyExists
to ensure the key doesn't already exist in the configuration.
public void AddKey(string strKey, string strValue)
{
XmlNode appSettingsNode =
xmlDoc.SelectSingleNode("configuration/appSettings");
try
{
if (KeyExists(strKey))
throw new ArgumentException("Key name: <" + strKey +
"> already exists in the configuration.");
XmlNode newChild = appSettingsNode.FirstChild.Clone();
newChild.Attributes["key"].Value = strKey;
newChild.Attributes["value"].Value = strValue;
appSettingsNode.AppendChild(newChild);
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory +
"..\\..\\App.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
catch (Exception ex)
{
throw ex;
}
}
Updating Key-Value Pairs
The following method updates an existing key value pair in the App.config. It will utilize the helper method KeyExists
to ensure we have a key to update.
public void UpdateKey(string strKey, string newValue)
{
if (!KeyExists(strKey))
throw new ArgumentNullException("Key", "<" + strKey +
"> does not exist in the configuration. Update failed.");
XmlNode appSettingsNode =
xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
childNode.Attributes["value"].Value = newValue;
}
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory +
"..\\..\\App.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
Deleting Key-Value Pairs
The following method will delete an existing key value pair from the App.config. It will utilize the helper method KeyExists
to ensure we have a key to delete.
public void DeleteKey(string strKey)
{
if (!KeyExists(strKey))
throw new ArgumentNullException("Key", "<" + strKey +
"> does not exist in the configuration. Update failed.");
XmlNode appSettingsNode =
xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
appSettingsNode.RemoveChild(childNode);
}
xmlDoc.Save(AppDomain.CurrentDomain.BaseDirectory + "..\\..\\App.config");
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
Helper Method
KeyExists
is a simple helper method that returns a boolean value indicating whether or not the targeted key actually exists in the App.config. It is used in all three of the above methods.
public bool KeyExists(string strKey)
{
XmlNode appSettingsNode =
xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode childNode in appSettingsNode)
{
if (childNode.Attributes["key"].Value == strKey)
return true;
}
return false;
}
Points of Interest
That's the long and the short of it. I'm not going to include a project, since the methods are fairly straightforward. Common sense would dictate that our application will require read/write permissions on the App.config in order to save changes. Also of particular note is the behavior of the configuration file. Once our Forms application has loaded, the App.config has already loaded, so, if you're doing something like, say, loading databases from the configuration, you probably won't want to use the common System.Configuration.ConfigurationSettings.AppSettings["key"]
syntax. You're better off looping through the App.config as an XML document, like so:
private void loadFromConfig()
{
this.lstDatabases.Items.Clear();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory +
"..\\..\\App.config");
XmlNode appSettingsNode =
xmlDoc.SelectSingleNode("configuration/appSettings");
foreach (XmlNode node in appSettingsNode.ChildNodes)
{
ListViewItem lvi = new ListViewItem();
string connStr = node.Attributes["value"].Value.ToString();
string keyName = node.Attributes["key"].Value.ToString();
lvi.Text = keyName;
lvi.SubItems.Add(connStr);
this.lvDatabases.Items.Add(lvi);
}
}
Happy coding!