使用.Net配置框架加载具有所需子ConfigurationElement的ConfigurationSection

我有一个控制台应用程序试图从web.config文件加载CustomConfigurationSection。

自定义配置部分具有所需的自定义配置元素。 这意味着当我加载配置部分时,如果配置中不存在该配置元素,我希望看到exception。 问题是.NET框架似乎完全忽略了isRequired属性。 因此,当我加载配置部分时,我只创建自定义配置元素的实例并将其设置在配置部分。

我的问题是,为什么会发生这种情况? 我希望GetSection()方法触发ConfigurationErrorsexception,因为配置中缺少必需的元素。

这是我的配置部分的外观。

public class MyConfigSection : ConfigurationSection { [ConfigurationProperty("MyConfigElement", IsRequired = true)] public MyConfigElement MyElement { get { return (MyConfigElement) this["MyConfigElement"]; } } } public class MyConfigElement : ConfigurationElement { [ConfigurationProperty("MyAttribute", IsRequired = true)] public string MyAttribute { get { return this["MyAttribute"].ToString(); } } } 

这是我加载配置部分的方法。

  class Program { public static Configuration OpenConfigFile(string configPath) { var configFile = new FileInfo(configPath); var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name); var wcfm = new WebConfigurationFileMap(); wcfm.VirtualDirectories.Add("/", vdm); return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/"); } static void Main(string[] args) { try{ string path = @"C:\Users\vrybak\Desktop\Web.config"; var configManager = OpenConfigFile(path); var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; MyConfigElement elem = configSection.MyElement; } catch (ConfigurationErrorsException ex){ Console.WriteLine(ex.ToString()); } } 

这是我的配置文件的样子。

    

奇怪的是,如果我打开配置文件并连续加载该部分2次,我将得到我期望的exception。

 var configManager = OpenConfigFile(path); var configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; configManager = OpenConfigFile(path); configSection = configManager.GetSection("MyConfigSection") as MyConfigSection; 

如果我使用上面的代码,那么exception将触发并告诉我MyConfigElement是必需的。 问题是为什么第一次不抛出这个exception?

Eric在MS论坛上回答了这个问题

引用他的回答:

应用于子对象(从ConfigurationElement派生)时,ConfigurationPropertyAttribute的IsRequired成员不起作用

我发现最好的解决方法是手动迭代ConfigurationElement类型的所有嵌套属性,并在获取该部分后自行检查。 如果一个元素是必需的但在文件中不存在,我只抛出一个ConfigurationErrorsException。

这是我的代码。

 private void ProcessMissingElements(ConfigurationElement element) { foreach (PropertyInformation propertyInformation in element.ElementInformation.Properties) { var complexProperty = propertyInformation.Value as ConfigurationElement; if (complexProperty == null) continue; if (propertyInformation.IsRequired && !complexProperty.ElementInformation.IsPresent) throw new ConfigurationErrorsException("ConfigProperty: [{0}] is required but not present".FormatStr(propertyInformation.Name)); if (!complexProperty.ElementInformation.IsPresent) propertyInformation.Value = null; else ProcessMissingElements(complexProperty); } } 

您是否尝试将其直接分配给正确类型的变量,即MyConfigSection而不是var? 这是我在两行代码之间看到的唯一区别。 (即在第二行中,var现在采用了特定类型)。