.NET 4.8中如何处理含不支持属性的ConfigurationSection?
问题:.NET 4.8环境下加载包含废弃属性的ConfigurationSection
在.NET 4.8中,当配置文件包含已不再支持的配置节点时,如何正常加载ConfigurationSection?如果更新System.Configuration.ConfigurationSection时移除了不再支持的ConfigurationProperty,能否让客户无需修改.config文件即可正常加载?
示例场景
原配置节定义:
public class CustomConfigSection : ConfigurationSection { [ConfigurationProperty("supportedFeatureConfiguration")] public SupportedFeatureConfigElement SupportedFeatureConfig => (SupportedFeatureConfigElement)base["supportedFeatureConfiguration"]; [ConfigurationProperty("unsupportedFeatureConfiguration")] public UnsupportedFeatureConfigElement UnsupportedFeatureConfig => (UnsupportedFeatureConfigElement)base["unsupportedFeatureConfiguration"]; }
版本更新后移除废弃属性:
public class CustomConfigSection : ConfigurationSection { [ConfigurationProperty("supportedFeatureConfiguration")] public SupportedFeatureConfigElement SupportedFeatureConfig => (SupportedFeatureConfigElement)base["supportedFeatureConfiguration"]; }
当前加载配置的代码:
private void DummyCode() { var configuration = ConfigurationManager.OpenExeConfiguration("My Config Path"); var mySection = configuration.Sections.Cast<ConfigurationSection>().FirstOrDefault(c => c.SectionInformation.Name == "My Section Name"); if (mySection == null) { return; } using (var fs = new FileStream("My File Name", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var xmlDoc = XDocument.Load(fs); mySection.SectionInformation.SetRawXml(xmlDoc.ToString()); } }
直接移除属性后加载会抛出未识别节点错误,需避免要求所有用户修改.config文件的破坏性变更,寻求更简洁的兼容方案。
可行解决方案
1. 重写DeserializeElement方法忽略未知节点
这是最简洁且长效的方案,通过重写配置节的DeserializeElement方法,自动跳过无法识别的废弃节点,无需修改客户配置:
public class CustomConfigSection : ConfigurationSection { [ConfigurationProperty("supportedFeatureConfiguration")] public SupportedFeatureConfigElement SupportedFeatureConfig => (SupportedFeatureConfigElement)base["supportedFeatureConfiguration"]; protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) { while (reader.NodeType != XmlNodeType.EndElement) { if (reader.Name == "supportedFeatureConfiguration") { // 仅处理仍支持的节点 base.DeserializeElement(reader, serializeCollectionKey); } else { // 跳过所有未知节点(包括废弃的unsupportedFeatureConfiguration) reader.Skip(); } } } }
2. 预处理XML移除废弃节点后加载
如果不想修改配置节类,可以在加载XML时提前移除废弃节点,再传入配置节:
private void DummyCode() { var configuration = ConfigurationManager.OpenExeConfiguration("My Config Path"); var mySection = configuration.Sections.Cast<ConfigurationSection>().FirstOrDefault(c => c.SectionInformation.Name == "My Section Name"); if (mySection == null) { return; } using (var fs = new FileStream("My File Name", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var xmlDoc = XDocument.Load(fs); // 移除所有废弃的配置节点 xmlDoc.Descendants("unsupportedFeatureConfiguration").Remove(); mySection.SectionInformation.SetRawXml(xmlDoc.ToString()); } }
3. 保留废弃属性但标记为忽略(过渡方案)
若需快速兼容且可接受少量冗余代码,可保留废弃属性并标记为Obsolete,同时设置非必填:
public class CustomConfigSection : ConfigurationSection { [ConfigurationProperty("supportedFeatureConfiguration")] public SupportedFeatureConfigElement SupportedFeatureConfig => (SupportedFeatureConfigElement)base["supportedFeatureConfiguration"]; [Obsolete("此配置已废弃,将被忽略")] [ConfigurationProperty("unsupportedFeatureConfiguration", IsRequired = false)] public UnsupportedFeatureConfigElement UnsupportedFeatureConfig => null; // 不实际读取配置值 }
内容的提问来源于stack exchange,提问作者r_h_w
相关产品推荐
相关产品推荐

