6

I'm developing a C# WPF MVVM application with .NET Framework 4.6.1 and I have a custom section in App.config:

<configuration>
    <configSections>
        <section name="SpeedSection" type="System.Configuration.NameValueSectionHandler" />
    </configSections>
    <SpeedSection>
        <add key="PrinterSpeed" value="150" />
        <add key="CameraSpeed" value="150" />
    </SpeedSection>
</configuration>

I want to modify PrinterSpeed and CameraSpeed from my app. I have tried this code:

static void AddUpdateAppSettings(string key, string value)
{
    try
    {
        var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var settings = configFile.AppSettings.Settings;
        if (settings[key] == null)
        {
            settings.Add(key, value);
        }
        else
        {
            settings[key].Value = value;
        }
        configFile.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
    }
    catch (ConfigurationErrorsException)
    {
        Console.WriteLine("Error writing app settings");
    }
}

But it doesn't work because I'm not modifying AppSettings section.

How can I modify those values?

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
VansFannel
  • 45,055
  • 107
  • 359
  • 626
  • I am adding this as a comment because it's not really an answer to your question, but might help you. Have you looked at alternatives to the very awkward and frustrating Microsoft solution. There are much better application configuration alternatives, for example the NuGet Urchin package. – bikeman868 Nov 22 '16 at 09:03

2 Answers2

6

System.Configuration.NameValueSectionHandler is hard to work with. You can replace it with System.Configuration.AppSettingsSection without touching anything else:

<configuration>
    <configSections>
        <section name="SpeedSection" type="System.Configuration.AppSettingsSection" />
    </configSections>
    <SpeedSection>
        <add key="PrinterSpeed" value="150" />
        <add key="CameraSpeed" value="150" />
    </SpeedSection>
</configuration>

And then change your method as follows:

static void AddUpdateAppSettings(string key, string value)
{
    try
    {
        var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        var settings = ((AppSettingsSection) configFile.GetSection("SpeedSection")).Settings;                                
        if (settings[key] == null)
        {
            settings.Add(key, value);
        }
        else
        {
            settings[key].Value = value;
        }
        configFile.Save(ConfigurationSaveMode.Modified);
        ConfigurationManager.RefreshSection(configFile.AppSettings.SectionInformation.Name);
    }
    catch (ConfigurationErrorsException)
    {
        Console.WriteLine("Error writing app settings");
    }
}
Evk
  • 98,527
  • 8
  • 141
  • 191
  • I'm doing `((AppSettingsSection) configFile.GetSection("SpeedSection")).Settings;` and I get the error: `Cannot convert 'System.Configuration.KeyValueInternalCollection' into 'System.Configuration.AppSettingsSection'.` – VansFannel Nov 22 '16 at 10:22
  • I did test this code exactly as described in answer and ensured it works. Maybe you have changed\added something? – Evk Nov 22 '16 at 10:37
  • Yes, sorry. It was my mistake. – VansFannel Nov 22 '16 at 10:38
0

You should use ConfigurationSection class. This tutorial could help: https://msdn.microsoft.com/en-us/library/2tw134k3.aspx

Sudet
  • 98
  • 1
  • 11
  • I'm not sure if I have understood that tutorial but I know how to access that configuration data but I don't know how to modify it and save the changes on App.config. – VansFannel Nov 22 '16 at 09:03
  • In your code you're accessing section AppSettings and editing it var settings = configFile.AppSettings.Settings; – Sudet Nov 22 '16 at 09:13
  • Instead of doing it you should create your custom config section class and access it using SpeedSection settings = ConfigurationManager.GetSection("SpeedSection") as SpeedSection Then you could save it as you're doing it right now. – Sudet Nov 22 '16 at 09:15