How to modify app.config at runtime

When you try to modify the app.config at runtime, if you don’t do it right, you’ll run into a few problems:

  • You’ll get the following exception:

System.Configuration.ConfigurationErrorsException: The configuration is read only.

  • The updated value isn’t persisted. When you re-open your program, the value you changed is still the old value.

This article will show you how to update the app.config the right way to avoid these problems. This shows three different scenarios: inserting a new connection string, modifying an existing connection string, and changing an app setting value.

Note: app.config is an XML-based config file that was used in .NET Framework (before .NET Core). In newer versions of .NET, the config file is JSON-based and called appsettings.json.

First, here’s the example app.config

This article will use the following app.config as a starting point. The code deals with the appSettings and connectionStrings sections.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
  <appSettings>
    <add key="DefaultConnectionStringName" value="TestSQL"/>
  </appSettings>
    <connectionStrings>
        <add name="TestSQL" connectionString="Data Source=QAServer;Initial Catalog=BirdsDB;Integrated Security=True"/>
    </connectionStrings>
</configuration>
Code language: HTML, XML (xml)

App.config is the name of the config file in Visual Studio. When the program is actually running, it’s called ExecutableName.exe.config (note: ExecutableName is a placeholder that refers to your executable file name). I’ll refer to the runtime app.config as ExecutableName.exe.config in this article.

Inserting a new connection string in the connectionStrings section

The following code shows how to insert a new connection string (used for executing SQL queries).

private void SaveConnectionString(string name, string connectionString)
{
	var conStringSetting = new ConnectionStringSettings(name, connectionString);

	var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
	config.ConnectionStrings.ConnectionStrings.Add(conStringSetting);
	config.Save(ConfigurationSaveMode.Modified);

	ConfigurationManager.RefreshSection("connectionStrings");

}
Code language: C# (cs)

Call this code with the following:

var sqlConBuilder = new SqlConnectionStringBuilder()
{
	InitialCatalog = "BirdsDB",
	DataSource = "QA",
	IntegratedSecurity = true
};

SaveConnectionString("QADatabase", sqlConBuilder.ConnectionString);
Code language: C# (cs)

Running the above code inserts a new connection string with name QADatabase into the runtime ExecutableName.exe.config file.

<connectionStrings>
	<add name="TestDB" connectionString="Data Source=Prod;Initial Catalog=BirdsDB;Integrated Security=True" />
	<add name="QADatabase" connectionString="Data Source=QA;Initial Catalog=BirdsDB;Integrated Security=True" />
</connectionStrings>
Code language: HTML, XML (xml)

Modifying an existing connection string in the connectionStrings section

The following code modifies an existing connection string.

private void ModifyConnectionString(string name, string connectionString)
{
	var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
	var section = (ConnectionStringsSection)config.GetSection("connectionStrings");
	section.ConnectionStrings[name].ConnectionString = connectionString;
	config.Save(ConfigurationSaveMode.Modified);

	ConfigurationManager.RefreshSection("connectionStrings");
}
Code language: C# (cs)

Call this code with the following:

var sqlConBuilder = new SqlConnectionStringBuilder()
{
	InitialCatalog = "BirdsDB",
	DataSource = "QA2",
	IntegratedSecurity = true
};

ModifyConnectionString("QADatabase", sqlConBuilder.ConnectionString);
Code language: C# (cs)

Running the above code modifies the existing QADatabase connection string in the runtime ExecutableName.exe.config file.

    <connectionStrings>
        <add name="TestDB" connectionString="Data Source=Prod;Initial Catalog=BirdsDB;Integrated Security=True" />
        <add name="QADatabase" connectionString="Data Source=QA2;Initial Catalog=BirdsDB;Integrated Security=True" />
    </connectionStrings>
Code language: HTML, XML (xml)

Updating an existing setting in the appSettings section

The following code shows how to modify an existing appSetting value.

private void SetDefaultConnectionString(string connectionStringName)
{
	var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
	config.AppSettings.Settings["DefaultConnectionStringName"].Value = connectionStringName;
	config.Save(ConfigurationSaveMode.Modified);

	ConfigurationManager.RefreshSection("appSettings");
}
Code language: C# (cs)

Call this code with the following:

SetDefaultConnectionString("QADatabase");
Code language: C# (cs)

Running the above code modifies the DefaultConnectionStringName setting in the runtime ExecutableName.exe.config file.

<appSettings>
	<add key="DefaultConnectionStringName" value="QADatabase" />
</appSettings>
Code language: HTML, XML (xml)

Warning: Watch out for access errors

If you try to update the app.config at runtime while running the exe from /Program Files/ you’ll run into the following error:

System.Configuration.ConfigurationErrorsException: An error occurred loading a configuration file: Access to the path is denied.

You can run your app as admin or put proper permissions to overcome this problem.

2 thoughts on “How to modify app.config at runtime”

  1. This method adds a new connectionString. What if the connection string is already there. And I answer: they key lies in the replace method of the connectionString property.

    ConnectionStringSettings ConStrSettings =
    ConfigurationManager.ConnectionStrings["<YourConnStringName>"];

    // Write the new path to the XML file connectionStrings section
    ConfigConnString = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    ConStrSettings.ConnectionString.Replace(ConStrSettings.ConnectionString,newConnString); //Replace existing string with new
    ConfigConnString.Save(ConfigurationSaveMode.Full);

    // Refresh the ConnectionString section to ensure the new value can be retrieved when needed without closing and re-opening // the program
    ConfigurationManager.RefreshSection(ConfigConnString.ConnectionStrings.SectionInformation.Name);

    Reply
    • Thanks for sharing Rowland!

      I tried your code, but it’s not updating the app.config.
      ConStrSettings.ConnectionString is a string. So ConStrSettings.ConnectionString.Replace(…, …) is calling the string Replace(old, new) method. This method returns a new string with the replaced valued. It doesn’t create a new string. In other words, this line:
      ConStrSettings.ConnectionString.Replace(ConStrSettings.ConnectionString, connectionString);
      is not doing anything.

      I thought you might be missing the part where it sets the ConnectionString with the new value, like this:
      ConStrSettings.ConnectionString = ConStrSettings.ConnectionString.Replace(ConStrSettings.ConnectionString, connectionString);
      But this leads to “ConfigurationErrorsException: The configuration is read only”.

      The following code works though. This replaces the existing connection string:
      Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
      ConnectionStringsSection section = config.GetSection("connectionStrings") as ConnectionStringsSection;
      if (section != null)
      {
      section.ConnectionStrings[name].ConnectionString = connectionString;
      config.Save(ConfigurationSaveMode.Modified);
      }
      ConfigurationManager.RefreshSection("connectionStrings");

      Note: I saw your comment about it deleting the placeholder text. I edited your comment and put it back with escaped < > (the comment system removes anything between un-escaped < >)

      Reply

Leave a Reply to Maclain Wiltzer Cancel reply