Write appSettings in external file

2019-01-18 14:28发布

I have a config file app.exe.config and appSettings section has something like this:

<configuration>
    <appSettings configSource="app.file.config" />
</configuration>

app.file.config file has something like this:

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
  <add key="var1" value="value 1" />
  <add key="var2" value="value 2" />
  <add key="var3" value="value 3" />
</appSettings>

I need to edit var1, var2 and var3 at runtime and I have code like this:

Configuration config = ConfigurationManager.OpenExeConfiguration("...path\app.exe);

config.AppSettings.SectionInformation.ConfigSource = "app.file.config";

config.AppSettings.Settings["var1"].Value = "value 11";
config.AppSettings.Settings["var2"].Value = "value 22";
config.AppSettings.Settings["var3"].Value = "value 33";
config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

When I run config.Save.... the file app.file.config has a appSettings node with an attribute "file". This attribute has the value to app.file.config

<appSettings file="app.file.config">
<add key="var1" value="value 1" />
  <add key="var2" value="value 2" />
  <add key="var3" value="value 3" />
</appSettings>

Now, if I try to load the config file, I have an exception with message "Unrecognized attribute 'file'. Note that attribute names are case-sensitive." in app.file.config.

If I delete the file attribute manually, the configuration file is loaded properly.

Any ideas?

How can avoid to write file attribute when I save config files.

Thanks

标签: c# .net config
3条回答
手持菜刀,她持情操
2楼-- · 2019-01-18 15:15

using an external config file is transparent for the application,

this part is o.k

</configuration>
    <appSettings configSource="app.file.config" />
</configuration>

and also this:

<?xml version="1.0" encoding="utf-8" ?>

<appSettings>
  <add key="var1" value="value 1" />
  <add key="var2" value="value 2" />
  <add key="var3" value="value 3" />
</appSettings>

change your code to be like this:

Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
config.AppSettings.Settings["var1"].Value = "value 11";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");

referring an external configuration file is transparent to the application, so you don't have to call it directly. you can use the default appSetting section in the configuration manager.

Good luck

查看更多
来,给爷笑一个
3楼-- · 2019-01-18 15:26

Finally, I have found a solution.

The solution is to declare the config file as this:

<appSettings configSource="app.file.config">
<add key="var1" value="value 1" />
  <add key="var2" value="value 2" />
  <add key="var3" value="value 3" />
</appSettings>

And from code

Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
AppSettingsSection myAppSettings = config.GetSection("appSettings")
myAppSettings.Settings["var1"].Value = "value 11";
config.Save(ConfigurationSaveMode.Modified);

Note that I use GetSection("appSettings") instead of config.AppSettings.Settings

Thanks to all that help people in StackOverflow.

查看更多
神经病院院长
4楼-- · 2019-01-18 15:30

WARNING: configSource is not the correct answer, as reported in other answers.

Now for the bad news... none of the external files will save if you update the value read in by ConfigurationManager.

Setup: Commandline project app.config file:

<appSettings file="AppSettings.config">
  <add key="test" value="MAIN" />
</appSettings>

AppSettings.config file with 'Copy to Output Directory'= 'Copy Always'

<?xml version="1.0" encoding="utf-8"?>
<appSettings>
  <add key="test" value="OVERRIDDEN"/>
</appSettings>

Program.cs:

        Console.WriteLine("Local Config sections");
        try
        {
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            Console.WriteLine("[test]=" + config.AppSettings.Settings["test"].Value);
            Console.WriteLine("[testExternalOnly]=" + config.AppSettings.Settings["testExternalOnly"].Value);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.WriteLine("press the ENTER key to end");
        Console.ReadLine();

TEST1 - appsettings overridden by sub-config 'configSource' file

Arrange:

Change app.config to use 'configSource'

<appSettings configSource="AppSettings.config">

Act: RunProject

Assert: Exception Raised: "Sections must only appear once per config file."

TEST2 - appsettings overridden by sub-config 'configSource' file

Arrange:

Change app.config to use 'file'

<appSettings file="AppSettings.config">

Act: RunProject

Assert:

config.AppSettings.Settings["test"].Value = OVERRIDDEN

config.AppSettings.Settings["testExternalOnly"].Value = INITIALSTATE

Now for the bad news... none of the external files will save if you use

config.AppSettings.Settings["test"].Value = "NEW";

The AppSettings will only save in the .exe.config file, and then if you close and open your config the values will be overwritten by the external file values.

TEST3- Values in External Files are not updated on 'config.Save'

Setup: Program.cs changed to:

    Console.WriteLine("Local Config sections");
    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    Console.WriteLine("BEFORE[test]=" + config.AppSettings.Settings["test"].Value);
    Console.WriteLine("BEFORE[testExternalOnly]=" + config.AppSettings.Settings["testExternalOnly"].Value);


    config.AppSettings.Settings["test"].Value = "NEW";
    config.AppSettings.Settings["testExternalOnly"].Value = "NEWEXTERNAL";

    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("appSettings");

    //Shut current config
    config = null;

    //Open config
    config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

    Console.WriteLine("AFTER[test]=" + config.AppSettings.Settings["test"].Value);
    Console.WriteLine("AFTER[testExternalOnly]=" + config.AppSettings.Settings["testExternalOnly"].Value);

    Console.WriteLine("AFTER CONFIG EXTERNAL FILE: " + System.IO.File.ReadAllText("AppSettings.config"));

    Console.WriteLine("AFTER CONFIG FILE: " + System.IO.File.ReadAllText(System.AppDomain.CurrentDomain.FriendlyName + ".config"));

Act: Run Program

Assert:

{myExe}.exe.confg's AppSettings section is:

<appSettings file="AppSettings.config">
  <add key="test" value="NEW" />
  <add key="testExternalOnly" value="NEWEXTERNAL" />
</appSettings>

AppSettings.config is unchanged

查看更多
登录 后发表回答