Update App.Config System.Net Setting at Runtime

update app.config file at runtime

You are using applicationSettings not appSettings.

The two are different sections of you config file.

To use an entry in the applicationSettings you use this syntax:

string result = Client.Properties.Settings.Default.client_postCodeRef_Service;

also note that you can't easily change the value of an applicationSetting entry from inside your program.

A detailed discussion on the pros and cons of applicationSettings and AppSettings can be found here

Change app.config programmatically at the runtime

Because you are using a custom section you need to do it with:

var xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
var path = @"//oracle.manageddataaccess.client/version/settings/setting[@name='TNS_ADMIN']";
var attrs = xmlDoc.SelectSingleNode(path).Attributes["value"].Value = "some value";
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
ConfigurationManager.RefreshSection(path);

This should work in case of default appSettings section:

System.Configuration.Configuration cnf = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cnf.AppSettings.Settings["TNS_ADMIN"].Value = "my value";
cnf.Save(ConfigurationSaveMode.Modified);

Documentation

Modify app.config system.diagnostics section at runtime

You can locate the path to the app.exe.config file through the ConfigurationManager, then load the config file as an XDocument.

string configPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath;

XDocument config = XDocument.Load(configPath);
XElement diagnostics = config.Descendants().FirstOrDefault(e => e.Name == "system.diagnostics");

if (diagnostics == default(XElement))
{
/// <system.diagnostics> element was not found in config
}
else
{
/// make changes within <system.diagnostics> here...
}

config.Save(configPath);

Trace.Refresh(); /// reload the trace configuration

Once the required changes are made, save the XDocument back to disk, and call Trace.Refresh() to reload the trace configuration.

See MSDN regarding the Trace.Refresh method here.

How to modify my App.exe.config keys at runtime?

System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

config.AppSettings.Settings["UserId"].Value = "myUserId";
config.Save(ConfigurationSaveMode.Modified);

You can read about ConfigurationManager here

Changing App.config at Runtime

UPDATE

The solution below did not work because XmlDocument does not dispose and it seems some versions of .net do not close correctly when given a file path. The solution (example code in the link) is to open a stream which will do a dispose and pass that stream to the save function.

A solution is shown here. http://web-beta.archive.org/web/20150107004558/www.devnewsgroups.net/group/microsoft.public.dotnet.xml/topic40736.aspx


Old stuff below

Try this:

Note, I changed to xpath, but it has been a while so I might have gotten the xpath wrong, but in any case you should use xpath and not walk the tree. As you can see it is much clearer.

The important point is the using statement which will dispose(), which I think was your problem.

Let me know, good luck.

  public void UpdateAppSettings(string key, string value)
{
using (XmlDocument xmlDoc = new XmlDocument())
{
xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
xmlDoc.DocumentElement.FirstChild.SelectSingleNode("descendant::"+key).Attributes[0].Value = value;
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
System.Configuration.ConfigurationManager.RefreshSection("section/subSection");
}

Change default app.config at runtime

The hack in the linked question works if it is used before the configuration system is used the first time. After that, it doesn't work any more.

The reason:

There exists a class ClientConfigPaths that caches the paths. So, even after changing the path with SetData, it is not re-read, because there already exist cached values. The solution is to remove these, too:

using System;
using System.Configuration;
using System.Linq;
using System.Reflection;

public abstract class AppConfig : IDisposable
{
public static AppConfig Change(string path)
{
return new ChangeAppConfig(path);
}

public abstract void Dispose();

private class ChangeAppConfig : AppConfig
{
private readonly string oldConfig =
AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();

private bool disposedValue;

public ChangeAppConfig(string path)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", path);
ResetConfigMechanism();
}

public override void Dispose()
{
if (!disposedValue)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfig);
ResetConfigMechanism();

disposedValue = true;
}
GC.SuppressFinalize(this);
}

private static void ResetConfigMechanism()
{
typeof(ConfigurationManager)
.GetField("s_initState", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, 0);

typeof(ConfigurationManager)
.GetField("s_configSystem", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);

typeof(ConfigurationManager)
.Assembly.GetTypes()
.Where(x => x.FullName ==
"System.Configuration.ClientConfigPaths")
.First()
.GetField("s_current", BindingFlags.NonPublic |
BindingFlags.Static)
.SetValue(null, null);
}
}
}

Usage is like this:

// the default app.config is used.
using(AppConfig.Change(tempFileName))
{
// the app.config in tempFileName is used
}
// the default app.config is used.

If you want to change the used app.config for the whole runtime of your application, simply put AppConfig.Change(tempFileName) without the using somewhere at the start of your application.

Can I get settings from app.config at run time rather than when compiled?

Found It!
The problem was occurring in a class library.
Although I create the settings in the class library and the settings get added to the app.config, it doesn't actually look there to retrieve them. Instead it's the web.config of the parent consuming the class library.
I put the settings in web.config and it appears to work.



Related Topics



Leave a reply



Submit