【问题标题】:.NET Config File: How to check if ConfigSection is present.NET 配置文件:如何检查 ConfigSection 是否存在
【发布时间】:2014-05-02 14:47:20
【问题描述】:

考虑:

行:

<section name="unity" />

方块:

<unity>
    <typeAliases />
    <containers />
</unity>

假设在缺少块时该行在 .config 文件中可用。

如何以编程方式检查块是否存在?

[编辑]

对于那些很快将问题标记为否定的天才:

我已经试过ConfigurationManager.GetSection()

var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

var section = config.GetSection("unity");

var sInfo = section.SectionInformation;

var isDeclared = sInfo.IsDeclared;

如果我弄错了,请纠正我,如果定义了 &lt;configSections&gt;(即使缺少实际的统一块),上述 not 是否会返回 null

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    由于ConfigurationSection 继承自ConfigurationElement,您可以使用ElementInformation 属性来判断是否在反序列化后找到了实际元素。

    使用此方法检测配置文件中是否缺少ConfigurationSection元素:

    //After Deserialization
    if(customSection.ElementInformation.IsPresent == false)
        Console.WriteLine("Section Missing");
    

    要确定是否缺少某个元素,您可以使用该部分中的属性(假设它称为“propName”),获取 propName 的 ElementInformation 属性并检查 IsPresent 标志:

    if(customSection.propName.ElementInformation.IsPresent == false)
        Console.WriteLine("Configuration Element was not found.");
    
       
    

    当然如果要检查定义是否缺失,使用如下方法:

    CustomSection mySection = 
        config.GetSection("MySection") as CustomSection;
    
    if(mySection is null)
        Console.WriteLine("ConfigSection 'MySection' was not defined.");
    

    -希望这有帮助

    【讨论】:

      【解决方案2】:

      使用ConfigurationManager.GetSection。如果该部分不存在,这将返回 null

      返回值

      类型:System.Object

      指定的 ConfigurationSection 对象,如果该部分不存在,则为 null。

      if (ConfigurationManager.GetSection("unity") == null)
      {
          Console.WriteLine("Section does not exist");
      }
      

      【讨论】:

      • 感谢@RB,但如果 Line 存在,这不会返回空值。
      • 如果我错了请纠正我,关键是如果定义了&lt;configSections&gt;ConfigurationManager.GetSection() 将不会为空(即使实际的统一 block不见了)。
      • 不幸的是,这是不正确的答案,当该部分已定义但不存在时,它将返回给定配置的默认实例(非空)。
      【解决方案3】:

      这是我解决这个问题的方法。

      var unitySection = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
      if (unitySection != null && unitySection.Containers.Count != 0)
          container.LoadConfiguration();
      

      第一次检查定义,第二次检查块

      【讨论】:

        【解决方案4】:

        您可以使用xml 阅读器打开配置文件并导航到名为“unity”的子元素,或者您可以在CreateMethod 内部实现IConfigurationSectionHandler,您可以区分传入节点并检查它是行还是块

          public class CustomConfigurationSectionHandler : IConfigurationSectionHandler { 
             public object Create(object parent, 
               object configContext, System.Xml.XmlNode section)
                   {
                         //check if section is a line , if yes return null
                         if( section ...)
                         { return null; }
                         //otherwise return whatever result you want :)
                         else {  }
                   }
           }
        

        处理程序当然需要在配置文件中注册,这样当你调用ConfigurationManager.GetSection("unity")时它就会被解析。

        【讨论】:

          【解决方案5】:

          与其他人类似,我认为您需要使用 ConfigurationManager.GetSection()。但是,如果我正确阅读了您的问题,您是否要求检查部分名称 =“Unity”中是否存在统一?如果是这样,您将需要执行以下操作:

          ConfigurationManager.GetSection("unity/unity");
          

          然后,您可以检查 cs 是否需要或执行类似于 RB 建议的操作。

          ***编辑***

          好的,这个怎么样,它有点啰嗦但可能有效:

          ConfigurationSection section = ConfigurationManager.GetSection("unity");
          System.Xml.XmlDocument xmlData = new System.Xml.XmlDocument();
          xmlData.LoadXml(section);
          
          XmlNode Found = null;
          
          foreach (System.Xml.XmlNode node in xmlData.ChildNodes)         
          {             
              if (node.HasChildNodes) 
              {        
                  Found = FindNode(node.ChildNodes, "unity"); 
              }          
          }
          
          if(Found == null) //do something   
          

          【讨论】:

          • 谢谢@sr28,如果我错了,请纠正我,关键是如果&lt;configSections&gt; 被定义,ConfigurationManager.GetSection() 不会为空(即使实际的统一 block 丢失)。
          • @dan - 看看我的编辑(未经测试)。当然,如果“unity”是“unity”部分下的唯一子节点,您可以在不使用 foreach 循环的情况下进行重组。
          【解决方案6】:

          我试图避免使用基于 XML 的解决方案。但似乎这是实现这一目标的唯一方法。

          列出下面的解决方案以供将来参考。

          [@sr28 和 @tchrikch 提出了相同的建议]

          if (XDocument
            .Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)
            .XPathSelectElement("/*[local-name() = 'configuration']/*[local-name() = 'unity']") == null)
          

          【讨论】:

            【解决方案7】:

            看到在.Net 5 应用程序中搜索同一问题的解决方案时出现了这个问题,我将把它留在这里。

            docs 中声明

            GetSection 永远不会返回 null。如果未找到匹配的部分,则 返回空的 IConfigurationSection。

            要查看该部分是否为空,请使用Exists 方法:

            var selection = Config.GetSection("section2");
            if (!selection.Exists())
            {
                throw new System.Exception("section2 does not exist.");
            }
            

            【讨论】:

              【解决方案8】:

              您可以打开配置文件并尝试通过配置名称访问配置。

              CustomSection customSection;
              
                          // Get the current configuration file.
                          System.Configuration.Configuration config =
                                  ConfigurationManager.OpenExeConfiguration(
                                  ConfigurationUserLevel.None);
              
                          // Create the section entry   
                          // in the <configSections> and the  
                          // related target section in <configuration>. 
                          if (config.Sections["CustomSection"] == null)
                          {
              

              enter link description here

              【讨论】:

              • 感谢@elmadj,但如果 Line 存在,这不会返回空值。
              【解决方案9】:

              我相信你可以使用ConfigurationManager.GetSection Method

              if(ConfigurationManager.GetSection(sectionName) == null)
              {
                // do something
              }
              

              【讨论】:

              • 感谢@Liath,但如果 Line 存在,这不会返回空值。
              • @dan 我已经反转它来检查是否丢失而不是丢失
              • 如果我错了请纠正我,关键是如果定义了&lt;configSections&gt;ConfigurationManager.GetSection() 将不会为空(即使实际的统一 block不见了)。
              猜你喜欢
              • 2017-11-22
              • 1970-01-01
              • 1970-01-01
              • 2017-08-23
              • 2012-04-11
              • 2021-12-02
              • 2016-12-30
              • 2011-11-01
              相关资源
              最近更新 更多