System.Configuration 始终保存默认值

System.Configuration always saving default values

对于我的项目,我需要一个与可执行文件存储在同一文件夹中的配置,并且用户可以轻松访问和编辑。我在 System.Configuration 包中找到了这个问题的解决方案,但现在我 运行 遇到了问题。问题是当我尝试保存配置文件时,它会创建它,但会用我假设的默认值填充所有值(因此字符串为空字符串,或 BlackConsoleColor

要保存并稍后检查配置,我使用以下代码:

static void Main()
{
        #if DEBUG
            string applicationName =
                Environment.GetCommandLineArgs()[0];
        #else
            string applicationName =
            Environment.GetCommandLineArgs()[0]+ ".exe";
        #endif

            string exePath = System.IO.Path.Combine(
                Environment.CurrentDirectory, applicationName);

            // Get the configuration file. The file name has
            // this format appname.exe.config.
            System.Configuration.Configuration config =
              ConfigurationManager.OpenExeConfiguration(exePath);

            try
            {

                // Create the custom section entry  
                // in <configSections> group and the 
                // related target section in <configuration>.
                if (config.Sections["CustomSection"] == null)
                {
                    ConsoleSection customSection = new ConsoleSection();
                    customSection.BackgroundColor = "Black";
                    customSection.ForegroundColor = "White";

                    config.Sections.Add("CustomSection", customSection);

                    // Save the configuration file.
                    customSection.SectionInformation.ForceSave = true;
                    config.Save(ConfigurationSaveMode.Full);

                    Console.WriteLine("Created configuration file: {0}",
                        config.FilePath);
                }
            }
            catch (ConfigurationErrorsException err)
            {
                Console.WriteLine("CreateConfigurationFile: {0}", err.ToString());
            }

            // Display feedback.
            Console.WriteLine();
            Console.WriteLine("Using OpenExeConfiguration(string).");
            // Display the current configuration file path.
            Console.WriteLine("Configuration file is: {0}",
              config.FilePath);

            ConsoleSection sect = config.GetSection("CustomSection") as ConsoleSection;

            Console.WriteLine("FG Color: {0}",
              sect.ForegroundColor);
            Console.WriteLine("BG Color: {0}",
              sect.BackgroundColor);

            return;
}

和 ConsoleSection class:

public class ConsoleSection : ConfigurationSection
{
    public ConsoleSection()
    {
    }

    [ConfigurationProperty("BackgroundColor", IsRequired=true)]
    public string BackgroundColor {
        get { return (string)(this["BackgroundColor"]); }
        set { this["BackgroundColor"] = value; } 
    }

    [ConfigurationProperty("ForegroundColor", IsRequired = true)]
    public string ForegroundColor
    {
        get { return (string)(this["ForegroundColor"]); }
        set { this["ForegroundColor"] = value; }
    }
}

我还注意到在第一个 运行 期间(当它应该保存东西时),它读取值就很好,所以如果你要保存这段代码并 运行 它,第一个 运行 会产生预期的输出。

代码以 .NET Core 3.1 为目标,如果重要的话。

有两点导致了这个错误。

  1. 缺少更新部分意味着您编写了仅用于添加新配置部分的代码。什么是 CustomSection 已经存在?
  2. 更新配置后需要刷新该部分。

请看下面的代码。如果它适用于所有测试用例。

void Main()
{
    #if DEBUG
        string applicationName = Environment.GetCommandLineArgs()[0];
    #else
        string applicationName = Environment.GetCommandLineArgs()[0] + ".exe";
    #endif

    string exePath = System.IO.Path.Combine(Environment.CurrentDirectory, applicationName);

    // Get the configuration file. The file name has
    // this format appname.exe.config.
    System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(@"E:\Temp\TwitterBot\TwitterBot\bin\Debug\TwitterBot.exe");

    try
    {

        // Create the custom section entry
        // in <configSections> group and the
        // related target section in <configuration>.
        if (config.Sections["CustomSection"] == null)
        {
            ConsoleSection customSection = new ConsoleSection();
            customSection.BackgroundColor = "Black";
            customSection.ForegroundColor = "White";

            config.Sections.Add("CustomSection", customSection);

            // Save the configuration file.
            customSection.SectionInformation.ForceSave = true;
            config.Save(ConfigurationSaveMode.Modified);

            Console.WriteLine("Created configuration file: {0}", config.FilePath);
        }
        //Missing Else Part
        else
        {
            config.Sections.Remove("CustomSection");

            ConsoleSection customSection = new ConsoleSection();
            customSection.BackgroundColor = "Red";
            customSection.ForegroundColor = "Pink";

            config.Sections.Add("CustomSection", customSection);
            customSection.SectionInformation.ForceSave = true;
            config.Save(ConfigurationSaveMode.Modified);
        }
    }
    catch (ConfigurationErrorsException err)
    {
        Console.WriteLine("CreateConfigurationFile: {0}", err.ToString());
    }

    //After updating the values you need to refresh the section before reading it.
    ConfigurationManager.RefreshSection("CustomSection");

    // Display feedback.
    Console.WriteLine();
    Console.WriteLine("Using OpenExeConfiguration(string).");
    // Display the current configuration file path.
    Console.WriteLine("Configuration file is: {0}", config.FilePath);

    ConsoleSection sect = config.GetSection("CustomSection") as ConsoleSection;

    Console.WriteLine("FG Color: {0}", sect.ForegroundColor);
    Console.WriteLine("BG Color: {0}", sect.BackgroundColor);

    return;
}

public class ConsoleSection : ConfigurationSection
{
    public ConsoleSection()
    {
    }

    [ConfigurationProperty("BackgroundColor", IsRequired = true)]
    public string BackgroundColor
    {
        get { return (string)(this["BackgroundColor"]); }
        set { this["BackgroundColor"] = value; }
    }

    [ConfigurationProperty("ForegroundColor", IsRequired = true)]
    public string ForegroundColor
    {
        get { return (string)(this["ForegroundColor"]); }
        set { this["ForegroundColor"] = value; }
    }
}