11

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

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

我的问题是,为什么会这样?我希望 GetSection() 方法触发 ConfigurationErrors 异常,因为配置中缺少必需的元素。

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

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());
            }
        }

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

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="MyConfigSection" type="configurationFrameworkTestHarness.MyConfigSection, configurationFrameworkTestHarness" />
  </configSections>

  <MyConfigSection>

  </MyConfigSection>

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

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

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

4

3 回答 3

4

我发现最好的解决方法是手动遍历所有 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);
    }
}
于 2010-03-22T12:31:06.153 回答
3

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

引用他的回答:

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

于 2010-03-19T06:36:21.030 回答
0

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

于 2010-03-22T12:12:42.703 回答