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

发布于 2024-08-25 19:47:58 字数 2504 浏览 2 评论 0原文

我有一个控制台应用程序正在尝试从 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>

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

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

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

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??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丢了幸福的猪 2024-09-01 19:47:58

我发现最好的解决方法是手动迭代 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);
    }
}

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);
    }
}
下壹個目標 2024-09-01 19:47:58

Eric 已回答此问题在MS论坛

引用他的回答:

IsRequired 成员
ConfigurationPropertyAttribute 确实
应用于儿童时不起作用
对象(从 ConfigurationElement 派生)

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)

心在旅行 2024-09-01 19:47:58

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

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文