【问题标题】:System.Configuration always saving default valuesSystem.Configuration 始终保存默认值
【发布时间】:2021-05-25 16:54:53
【问题描述】:

对于我的项目,我需要一个与可执行文件存储在同一文件夹中的配置,并且用户可以轻松访问和编辑。我在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 类:

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 为目标。

【问题讨论】:

    标签: c# .net-core app-config system.configuration


    【解决方案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; }
        }
    }
    

    【讨论】:

    • else 部分是不需要的,因为如果该部分已经存在,则需要加载它(这是配置文件的目的,不是吗?)。但除此之外,这解决了问题。
    猜你喜欢
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多