You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:06:37