我需要在根设置组中保存2个不同的设置组。应该像这样:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
........................
some_settings
........................
</sectionGroup>
<sectionGroup name="GROUP_2">
........................
some_other_settings
........................
</sectionGroup>
</sectionGroup>
</configSections>
................................
other_system_tags
................................
</configuration>
关键在于我需要在代码的不同位置逐个保存它们(例如,GROUP_1可能是连接字符串,GROUP_2是一些环境设置,它们都由用户在我的应用程序的不同部分填写)
我创建了这个简单的测试类来获得预期的结果
[TestFixture]
public class Tttt
{
private string ROOT_GROUP = "ROOT_GROUP";
private string GROUP_1 = "GROUP_1";
private string GROUP_2 = "GROUP_2";
[Test]
public void SaveSettingsGroups()
{
SaveGroup1();
SaveGroup2();
Assert.True(true);
}
private Configuration GetConfig()
{
var configFilePath = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
var map = new ExeConfigurationFileMap { ExeConfigFilename = configFilePath };
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
return config;
}
private void SaveGroup1()
{
var config = GetConfig();
var root = new UserSettingsGroup();
config.SectionGroups.Add(ROOT_GROUP, root);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
var nested = new UserSettingsGroup();
root.SectionGroups.Add(GROUP_1, nested);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested.Name);
}
private void SaveGroup2()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested = new UserSettingsGroup();
root.SectionGroups.Add(GROUP_2, nested);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested.Name);
}
}
但是由于某种原因,此代码的结果不同。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
........................
some_settings
........................
</sectionGroup>
</sectionGroup>
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_2">
........................
some_other_settings
........................
</sectionGroup>
</sectionGroup>
</configSections>
................................
other_system_tags
................................
</configuration>
ROOT_GROUP 节点被复制了,当我向已经存在的根组添加新的嵌套组并保存时,Visual Studio 抛出了一个异常,提示 ROOT_GROUP 已经存在。显然,我的问题隐藏在 SaveGroup2() 方法中 - 但是为什么呢?
更新: 我刚刚添加了一个新方法。
private void SaveGroup3()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested1 = root.SectionGroups.Get(0);
var nested2 = new UserSettingsGroup();
var nested3 = new UserSettingsGroup();
nested1.SectionGroups.Add("GROUP_2", nested2);
root.SectionGroups.Add("GROUP_3", nested3);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(nested2.Name);
ConfigurationManager.RefreshSection(nested3.Name);
}
替换它在测试中
[Test]
public void SaveSettingsGroups()
{
SaveGroup1();
SaveGroup3();
Assert.True(true);
}
发现了这种奇怪的行为
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1">
<sectionGroup name="GROUP_2">
</sectionGroup>
</sectionGroup>
<sectionGroup name="GROUP_3">
</sectionGroup>
</sectionGroup>
正如您所见,奇怪的地方在于结果完全符合预期。ROOT_GROUP并没有像我需要的那样重复,但为什么SaveGroup2()会出现这种情况呢?我在SaveGroup2()中漏掉了什么吗?
更新2 - 黑科技
只是尝试了一个简单的想法 - 如果在向其添加新嵌套元素之前清除root_group会发生什么?
private void SaveGroup2()
{
var config = GetConfig();
var root = config.GetSectionGroup(ROOT_GROUP);
var nested = new ConfigurationSectionGroup();
//Copy exiting nested groups to array
var gr = new ConfigurationSectionGroup[5];
root.SectionGroups.CopyTo(gr,0);
gr[1] = nested;
//<!----
root.SectionGroups.Clear();
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
root.SectionGroups.Add(gr[0].Name, gr[0]);
root.SectionGroups.Add(GROUP_2, gr[1]);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(root.Name);
}
你可能会猜到,它是如何运作的!
<sectionGroup name="ROOT_GROUP">
<sectionGroup name="GROUP_1" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
</sectionGroup>
<sectionGroup name="GROUP_2" type="System.Configuration.ConfigurationSectionGroup, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" >
</sectionGroup>
</sectionGroup>
我觉得这看起来像一个错误,或者是有一些我错过的隐藏的东西。有人可以解释一下我做错了什么吗?
ExeConfigurationFileMap
类或任何更改配置的类,它们都很糟糕。配置文件只是XML。使用XML类,如LINQ to XML。 - Jeremy Thompson