Loading a ConfigurationSection with a required child ConfigurationElement with .Net configuration framework

烈酒焚心 提交于 2019-12-22 03:32:28

问题


I have a console application that is trying to load a CustomConfigurationSection from a web.config file.

The custom configuration section has a custom configuration element that is required. This means that when I load the config section, I expect to see an exception if that config element is not present in the config. The problem is that the .NET framework seems to be completely ignoring the isRequired attribute. So when I load the config section, I just creates an instance of the custom configuration element and sets it on the config section.

My question is, why is this happening? I want the GetSection() method to fire a ConfigurationErrors exception since a required element is missing from the configuration.

Here is how my config section looks.

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

Here is how I load the config section.

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

Here is what my config file looks like.

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

  <MyConfigSection>

  </MyConfigSection>

The wierd part is that if I open the config file and load the section 2 times in a row, I will get the exception that I expect.

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

If I use the code above, then the exception will fire and tell me that MyConfigElement is required. The question is Why is it not throwing this exception the first time??


回答1:


I found that the best workaround for this was to manually iterate through all nested properties that of the ConfigurationElement type and check them myself after getting the section. If an element is required but is not present in the file I just throw a ConfigurationErrorsException.

Here is my code.

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



回答2:


Eric has answered this in the MS Forums

To quote his answer:

The IsRequired member of ConfigurationPropertyAttribute does not work when applied to a child object (deriving from ConfigurationElement)




回答3:


Did you try assigning it directly to the correct type of variable, i.e. MyConfigSection instead of var? That is the only difference I can see between the two lines of code. (i.e in the second line, var has now taken a specific type).



来源:https://stackoverflow.com/questions/2470996/loading-a-configurationsection-with-a-required-child-configurationelement-with

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!