【问题标题】:How to get the values of a ConfigurationSection of type NameValueSectionHandler如何获取 NameValueSectionHandler 类型的 ConfigurationSection 的值
【发布时间】:2011-03-28 13:07:20
【问题描述】:

我正在使用 C#,Framework 3.5 (VS 2008)。

我正在使用ConfigurationManager 将配置(不是默认的 app.config 文件)加载到配置对象中。

使用 Configuration 类,我能够获得 ConfigurationSection,但我找不到获取该部分值的方法。

在配置中,ConfigurationSection 的类型为 System.Configuration.NameValueSectionHandler

对于它的价值,当我使用 ConfigurationManager 的方法 GetSection 时(仅在我的默认 app.config 文件中有效),我收到了一个对象类型,我可以将其转换为对集合键值,我刚刚收到像字典一样的值。但是,当我从 Configuration 类收到 ConfigurationSection 类时,我无法进行此类转换。

编辑: 配置文件示例:

<configuration>
  <configSections>
    <section name="MyParams" 
             type="System.Configuration.NameValueSectionHandler" />
  </configSections>

  <MyParams>
    <add key="FirstParam" value="One"/>
    <add key="SecondParam" value="Two"/>
  </MyParams>
</configuration>

当它在 app.config 上时我能够使用它的方式示例(“GetSection”方法仅适用于默认的 app.config):

NameValueCollection myParamsCollection =
             (NameValueCollection)ConfigurationManager.GetSection("MyParams");

Console.WriteLine(myParamsCollection["FirstParam"]);
Console.WriteLine(myParamsCollection["SecondParam"]);

【问题讨论】:

  • 如果您使用 .Net 4.0 版,那么动态可能会有所帮助

标签: c# config configurationmanager configurationsection


【解决方案1】:

Here's 一个很好的帖子,展示了如何做到这一点。

如果要从 app.config 以外的文件中读取值,则需要将其加载到 ConfigurationManager 中。

试试这个方法:ConfigurationManager.OpenMappedExeConfiguration()

在 MSDN 文章中有一个如何使用它的示例。

【讨论】:

  • 正如我在帖子中所说,这就是我所做的。我收到了 Configuraion 类,并从中收到了 ConfigurationSection。我的问题是如何从 ConfigurationSection 对象中获取值?我没有问如何获取配置对象.. 还是谢谢!
  • 顺便说一句,在您给我的示例中,他们没有使用来自 OpenMappedExeConfiguration 的 Configuration 类,而是使用默认的 app.config(可以使用 .GetSection/. GetConfig 方法,但正如我在帖子中所说的那样——我已经这样做了。但这对我没有好处,因为它只对 app.config 有好处)。对于msdn,我在那里找不到我的问题的答案..
  • 好吧,我越看越发现它不容易做到。基本问题是您试图混合 .Net 1.1 配置样式代码和 2.0。阅读本文,它将为您指明正确的方向:eggheadcafe.com/software/aspnet/30832856/…
  • @MonkeyWrench 该页面不再可用。
  • 这个答案似乎受到链接腐烂的影响,这就是link only answers are discouraged的原因。
【解决方案2】:

尝试使用AppSettingsSection 而不是NameValueCollection。像这样的:

var section = (AppSettingsSection)config.GetSection(sectionName);
string results = section.Settings[key].Value;

来源: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/d5079420-40cb-4255-9b3b-f9a41a1f7ad2/

【讨论】:

  • 不,这样你会得到“无法将'System.Configuration.DefaultSection'类型的对象转换为'System.Configuration.AppSettingsSection'。”
  • @nerijus :拜托伙计……当然,Steven 的假设之一是您实际上相应地更改了部分的类型……无意冒犯,但您确实可以在发表评论之前考虑一下。我尝试了这个解决方案并且它有效。 +1 史蒂文
  • @h9uest:这不是那么简单,因为 Liran 写的部分是System.Configuration.NameValueSectionHandler。这个答案似乎更像是一种肮脏的黑客攻击。
【解决方案3】:

遇到确切的问题。问题是因为 .config 文件中的 NameValueSectionHandler。您应该改用 AppSettingsSection:

<configuration>

 <configSections>
    <section  name="DEV" type="System.Configuration.AppSettingsSection" />
    <section  name="TEST" type="System.Configuration.AppSettingsSection" />
 </configSections>

 <TEST>
    <add key="key" value="value1" />
 </TEST>

 <DEV>
    <add key="key" value="value2" />
 </DEV>

</configuration>

然后在 C# 代码中:

AppSettingsSection section = (AppSettingsSection)ConfigurationManager.GetSection("TEST");

顺便说一句,NameValueSectionHandler 在 2.0 中不再支持。

【讨论】:

  • 投射到 AppSettings 部分对我不起作用。相反,我已经转换为 NameValueCollection 并工作了。
  • 我在让我的部分正常工作时遇到了一些麻烦(在加载配置文件本身时出现了一些错误),但之后这个解决方案就完美地运行了。现在我可以将我的配置文件拆分为多个部分,并通过 AppSettingsSection 轻松访问这些值。
【解决方案4】:

这是一个老问题,但我使用以下课程来完成这项工作。它基于Scott Dorman's blog

public class NameValueCollectionConfigurationSection : ConfigurationSection
{
    private const string COLLECTION_PROP_NAME = "";

    public IEnumerable<KeyValuePair<string, string>> GetNameValueItems()
    {
        foreach ( string key in this.ConfigurationCollection.AllKeys )
        {
            NameValueConfigurationElement confElement = this.ConfigurationCollection[key];
            yield return new KeyValuePair<string, string>
                (confElement.Name, confElement.Value);
        }
    }

    [ConfigurationProperty(COLLECTION_PROP_NAME, IsDefaultCollection = true)]
    protected NameValueConfigurationCollection ConfCollection
    {
        get
        {
            return (NameValueConfigurationCollection) base[COLLECTION_PROP_NAME];
        }
    }

用法很简单:

Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
NameValueCollectionConfigurationSection config = 
    (NameValueCollectionConfigurationSection) configuration.GetSection("MyParams");

NameValueCollection myParamsCollection = new NameValueCollection();
config.GetNameValueItems().ToList().ForEach(kvp => myParamsCollection.Add(kvp));

【讨论】:

    【解决方案5】:

    我可以让它工作的唯一方法是手动实例化节处理程序类型,将原始 XML 传递给它,然后转换结果对象。

    看起来效率很低,但是你去吧。

    我写了一个扩展方法来封装这个:

    public static class ConfigurationSectionExtensions
    {
        public static T GetAs<T>(this ConfigurationSection section)
        {
            var sectionInformation = section.SectionInformation;
    
            var sectionHandlerType = Type.GetType(sectionInformation.Type);
            if (sectionHandlerType == null)
            {
                throw new InvalidOperationException(string.Format("Unable to find section handler type '{0}'.", sectionInformation.Type));
            }
    
            IConfigurationSectionHandler sectionHandler;
            try
            {
                sectionHandler = (IConfigurationSectionHandler)Activator.CreateInstance(sectionHandlerType);
            }
            catch (InvalidCastException ex)
            {
                throw new InvalidOperationException(string.Format("Section handler type '{0}' does not implement IConfigurationSectionHandler.", sectionInformation.Type), ex);
            }
    
            var rawXml = sectionInformation.GetRawXml();
            if (rawXml == null)
            {
                return default(T);
            }
    
            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(rawXml);
    
            return (T)sectionHandler.Create(null, null, xmlDocument.DocumentElement);
        }
    }
    

    在你的例子中你会这样称呼它:

    var map = new ExeConfigurationFileMap
    {
        ExeConfigFilename = @"c:\\foo.config"
    };
    var configuration = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
    var myParamsSection = configuration.GetSection("MyParams");
    var myParamsCollection = myParamsSection.GetAs<NameValueCollection>();
    

    【讨论】:

    • 很高兴看到有人回答所提问题。我一直在挖掘有关处理 OpenExeConfiguration GetSection 问题的大量答案,这些问题带有将人们重定向到 ConfigurationManager.GetSection 的“答案”,而这并不是一回事。
    • 您应该可以只调用 Get 方法:var myParamsCollection = myParamsSection.Get();
    【解决方案6】:

    以下是前面提到的this blog 的一些示例:

    <configuration>    
       <Database>    
          <add key="ConnectionString" value="data source=.;initial catalog=NorthWind;integrated security=SSPI"/>    
       </Database>    
    </configuration>  
    

    获取值:

     NameValueCollection db = (NameValueCollection)ConfigurationSettings.GetConfig("Database");         
        labelConnection2.Text = db["ConnectionString"];
    

    -

    另一个例子:

    <Locations 
       ImportDirectory="C:\Import\Inbox"
       ProcessedDirectory ="C:\Import\Processed"
       RejectedDirectory ="C:\Import\Rejected"
    />
    

    获取价值:

    Hashtable loc = (Hashtable)ConfigurationSettings.GetConfig("Locations"); 
    
    labelImport2.Text = loc["ImportDirectory"].ToString();
    labelProcessed2.Text = loc["ProcessedDirectory"].ToString();
    

    【讨论】:

      【解决方案7】:

      试试这个;

      信用:https://www.limilabs.com/blog/read-system-net-mailsettings-smtp-settings-web-config

      SmtpSection section = (SmtpSection)ConfigurationManager.GetSection("system.net/mailSettings/smtp");
      
      string from = section.From;
      string host = section.Network.Host;
      int port = section.Network.Port;
      bool enableSsl = section.Network.EnableSsl;
      string user = section.Network.UserName;
      string password = section.Network.Password;
      

      【讨论】:

        【解决方案8】:

        这就像一个魅力

        dynamic configSection = ConfigurationManager.GetSection("MyParams");
        var theValue = configSection["FirstParam"];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-28
          • 1970-01-01
          • 2017-06-01
          • 1970-01-01
          相关资源
          最近更新 更多