C#中使用ExeConfiguration向XML添加子对象的实现咨询
嘿,我来帮你搞定这个配置写入的问题!你遇到的核心问题是:当配置节中原本没有对应的子ConfigurationElement时,直接修改属性后配置系统不会自动识别并序列化它。下面是一步步的可行解决方案:
1. 确保子元素被正确初始化
在你的DataEnhancementToolConfigurationSection中,子元素属性的getter需要处理null情况——如果配置里还没有这个元素,就主动创建实例并关联到配置节:
public class DataEnhancementToolConfigurationSection : ConfigurationSection { [ConfigurationProperty(ConfigKeys.GoogleApiKeys)] public GoogleApiKeysConfigurationElementCollection GoogleApiKeys { get => (GoogleApiKeysConfigurationElementCollection)this[ConfigKeys.GoogleApiKeys] ?? new GoogleApiKeysConfigurationElementCollection(); set => this[ConfigKeys.GoogleApiKeys] = value; } [ConfigurationProperty(ConfigKeys.NameNormalizationAndGeocodingOptions)] public NameNormalizationOptionsConfigurationElement NameNormalizationAndGeocodingOptions { get { var element = (NameNormalizationOptionsConfigurationElement)this[ConfigKeys.NameNormalizationAndGeocodingOptions]; if (element == null) { element = new NameNormalizationOptionsConfigurationElement(); this[ConfigKeys.NameNormalizationAndGeocodingOptions] = element; } return element; } set => this[ConfigKeys.NameNormalizationAndGeocodingOptions] = value; } }
这样无论配置文件里有没有这个子元素,你访问属性时都能拿到有效的实例,后续修改也能被追踪到。
2. 修复ConfigurationHelper,确保新配置节被添加到配置文件
如果原本的配置文件里没有你的data-enhancement-tool-config节,你创建的新节实例必须手动添加到配置的Sections集合中,否则保存时不会写入XML:
public static class ConfigurationHelper { public static (Configuration configFile, T section) GetSectionFromRoamingConfiguration<T>(string sectionKey) where T : ConfigurationSection, new() { var configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming); var section = (T)configuration.GetSection(sectionKey); // 如果节不存在,创建新实例并添加到配置中 if (section == null) { section = new T(); section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser; configuration.Sections.Add(sectionKey, section); } else { section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser; } return (configuration, section); } }
3. 强制保存配置节的修改
有时候修改子元素的属性后,配置系统不会自动标记父节为“已修改”,所以在保存前手动强制标记:
private void NameNormalizationAndGeocodingForm_FormClosed(object sender, FormClosedEventArgs e) { var config = ConfigurationHelper .GetSectionFromRoamingConfiguration<DataEnhancementToolConfigurationSection>( ConfigKeys.DataEnhancementSectionName); // 直接修改子元素的各项属性 var targetOptions = config.section.NameNormalizationAndGeocodingOptions; targetOptions.CityColumnName = _nameNormalizationOptionsConfigurationElement.CityColumnName; targetOptions.PrintPlaceId = _nameNormalizationOptionsConfigurationElement.PrintPlaceId; targetOptions.PlaceIdColumnName = _nameNormalizationOptionsConfigurationElement.PlaceIdColumnName; targetOptions.PrintCompanyName = _nameNormalizationOptionsConfigurationElement.PrintCompanyName; targetOptions.CompanyNameColumnName = _nameNormalizationOptionsConfigurationElement.CompanyNameColumnName; // ... 其他需要修改的属性 // 强制标记节为需要保存,确保子元素的修改被写入 config.section.SectionInformation.ForceSave = true; config.configFile.Save(ConfigurationSaveMode.Modified); }
验证结果
完成以上修改后,保存配置后你的XML应该会新增对应的子元素,类似这样:
<data-enhancement-tool-config> <google-api-keys> <add google-key=":)" /> </google-api-keys> <name-normalization-and-geocoding-options printPlaceId="true" placeIdColumnName="PlaceId" printCompanyName="true" companyNameColumnName="CompanyName" /> </data-enhancement-tool-config>
这样就能成功把子对象写入XML配置文件啦!
内容的提问来源于stack exchange,提问作者Przemysław P.
相关产品推荐
相关产品推荐

