使用ConfigurationManager保存配置时抛出‘锁定时无法编辑配置节属性’异常
我来帮你拆解这个问题:你通过Visual Studio创建了Scope为User的应用设置,能正常读取,但用ConfigurationManager直接操作配置文件时,在configFile.Save()这一行抛出了锁定异常,而用自动生成的Properties.Settings.Default却能正常保存并生成user.config。
问题出在哪?
先看你的错误代码:
// 这段代码能正常读取 Console.WriteLine(Properties.Settings.Default.name); Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); KeyValueConfigurationCollection settings = configFile.AppSettings.Settings; settings.Add("Port", "12"); // 这里抛出异常 configFile.Save(ConfigurationSaveMode.Modified);
你操作的是configFile.AppSettings.Settings——这对应的是配置文件里的<appSettings>节点,但你的app.config里根本没有这个节点!当你尝试往不存在的<appSettings>节添加设置时,.NET会自动创建这个节,但默认情况下,AppSettingsSection是被锁定的(locked属性为true),所以保存时就会触发"ConfigurationSection properties cannot be edited when locked"异常。
而你通过VS创建的用户设置,实际存在于<userSettings>下的ConsoleApplication1.Properties.Settings节里,这是一个ClientSettingsSection类型的自定义配置节,和AppSettingsSection完全是两回事。Properties.Settings.Default是VS自动生成的封装类,专门用来操作这个自定义节,内部已经处理了节的锁定和序列化逻辑,所以能正常工作。
正确的操作方式
如果你一定要用ConfigurationManager来修改VS创建的用户设置,需要定位到对应的ClientSettingsSection,而不是去碰AppSettings。示例代码如下:
// 打开当前用户的配置文件 Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); // 获取userSettings节组 UserSettingsGroup userSettingsGroup = (UserSettingsGroup)configFile.SectionGroups["userSettings"]; // 获取VS生成的具体设置节 ClientSettingsSection settingsSection = (ClientSettingsSection)userSettingsGroup.Sections["ConsoleApplication1.Properties.Settings"]; // 查找是否已有"Port"设置 SettingElement portSetting = settingsSection.Settings.Get("Port"); if (portSetting == null) { // 如果没有,创建新的设置项,指定序列化方式为字符串 portSetting = new SettingElement("Port", SettingsSerializeAs.String); settingsSection.Settings.Add(portSetting); } // 设置值 portSetting.Value.ValueXml.InnerText = "12"; // 保存配置 configFile.Save(ConfigurationSaveMode.Modified); // 刷新配置,让新设置立即生效 ConfigurationManager.RefreshSection("userSettings/ConsoleApplication1.Properties.Settings");
当然,更推荐的还是用VS自动生成的Properties.Settings类,它已经帮你封装了所有复杂的配置操作,代码更简洁可靠:
// 直接修改设置 Properties.Settings.Default.Port = "12"; // 保存到user.config Properties.Settings.Default.Save(); // 可选:刷新让设置立即生效 Properties.Settings.Default.Reload();
总结
- 你混淆了两种不同的配置节类型:
AppSettingsSection(对应<appSettings>)和ClientSettingsSection(对应VS生成的<userSettings>下的自定义节) - 直接操作
AppSettings会触发锁定异常,因为默认该节是锁定状态 - 优先使用VS自动生成的
Properties.Settings类来管理应用设置,这是官方推荐的方式;如果需要手动用ConfigurationManager,要定位到正确的配置节
内容的提问来源于stack exchange,提问作者ALT user

