【问题标题】:Getting a StringCollection out of AppSettings through the configuration manager通过配置管理器从 AppSettings 中获取 StringCollection
【发布时间】:2009-08-05 21:12:22
【问题描述】:

我正在像这样访问我的程序集的配置:

ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = Assembly.GetExecutingAssembly().Location + ".config";
Configuration conf = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
AppSettingsSection appSettings = conf.AppSettings;

我的 .config 文件包含这样的部分

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="CsDll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
</configSections>
<connectionStrings>
    <add name="CsDll.Properties.Settings.SabreCAD" connectionString="A Connection string." />
    <add name="CsDll.Properties.Settings.StpParts" connectionString="Another connection string" />
</connectionStrings>
 <applicationSettings>
        <CsDll.Properties.Settings>
            <setting name="StpInsertSearchPath" serializeAs="Xml">
                <value>
                    <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                        <string>A string</string>
                        <string>Another string in the collection</string>

如果我编辑 .config 文件,我可以成功读取连接字符串,包括更改。所以,我知道我已连接到正确的文件。但是我在 appSettings 对象中找不到该字符串集合。它不在 .Settings KeyValueConfigurationCollection 中。我在哪里可以找到我的字符串集合?

【问题讨论】:

    标签: configuration c#-2.0 configurationmanager


    【解决方案1】:

    您应该使用这种更简单的语法访问集合中的项目

    foreach (string s in CsDll.Properties.Settings.Default.StpInsertSearchPath)
    {
        Console.WriteLine(s);
    }
    

    编辑:

    下面的代码应该可以解决问题

    ExeConfigurationFileMap map = new ExeConfigurationFileMap(); 
    map.ExeConfigFilename = Assembly.GetExecutingAssembly().Location + ".config"; 
    Configuration conf = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); 
    ConfigurationSectionGroup appSettingsGroup = conf.GetSectionGroup("applicationSettings");
    ClientSettingsSection clientSettings = (ClientSettingsSection) appSettingsGroup.Sections["CsDll.Properties.Settings"];
    ConfigurationElement element = clientSettings.Settings.Get("StpInsertSearchPath");
    string xml = ((SettingElement)element).Value.ValueXml.InnerXml;
    XmlSerializer xs = new XmlSerializer(typeof(string[]));
    string[] strings = (string[])xs.Deserialize(new XmlTextReader(xml, XmlNodeType.Element, null));
    foreach (string s in strings)
    {
        Console.WriteLine(s);
    }
    

    可能有更短的方法,但这对我有用。

    【讨论】:

    • 好的。我可以这样读取字符串数组。但是,字符串来自编译到程序集中的默认值。部署程序集后,我需要能够在该集合中添加、删除和更改字符串。 .Properties.Settings.Default 不会选择对 .config 文件的编辑。在我开始使用 ConfigurationManager 之前,连接字符串也有同样的问题。
    • 你可能需要访问ConfigurationManager的方法:ConfigurationManager.GetSection("applicationSettings");它应该返回您要分析的对象
    • ConfigurationManager.GetSection("applicationSettings") 返回 null
    • 请参考我的编辑。它在配置文件中找到合适的 XML 元素,然后使用标准的 Xml 序列化调用对其进行反序列化。
    • 见下面@Kevin Stout 的回答。对于此问题,这是一个更简单且更易于实施的解决方案。请注意,他的答案比原始答案晚了大约 2.5 年,但看起来是一个更好的答案,至少对于 VS2013 而言。
    【解决方案2】:

    如果它是您尝试从设置中提取的 StringCollection

    var strings = (StringCollection) Properties.Settings.Default["StpInsertSearchPath"];
    

    无需 XmlSerializer 即可完成同样多的工作

    【讨论】:

      【解决方案3】:

      AppSettings 和 ConnectionStrings 都是 ConfigurationManager 上直接可用的属性。

      但是,applicationSettingsuserSettings 对应于熟悉的 Settings.settings 可以在 VS 设置设计器中编辑,但并非如此容易上手。 AppSettings applicationSettings 相同,后者位于正在使用的配置文件的完全不同部分。

      您必须使用上述挖掘方法或变体来获取 applicationSettingsuserSettings。此外,applicationSettings 只会在您下次启动应用程序时更新,如果您甚至可以在运行时写入它们。

      例如(从别处抄袭 - 谢谢):

      public static string ReadSetting(string sectionGroupName, string sectionName, string settingName, Configuration config = null)
          {
              if (config == null)
                  config = SharedConfigSettings;
              // Get sectionGroup
              var sectionGroup =
                config.GetSectionGroup(sectionGroupName);
      
              // Get section
              var section =
                (ClientSettingsSection)sectionGroup.Sections.Get(sectionName);
              // Get setting
              var setting = section.Settings.Get(settingName);
              // Read setting value
              return setting.Value.ValueXml.InnerText;
          }
      

      再举一个例子(来自许多例子——感谢世界):

      ///<summary>
          /// return the applicationSettings section 
          ///</summary>
          ///<returns></returns>
          public static ClientSettingsSection GetSettingsSection(ConfigurationSectionGroup group, string clientSectionName)
          {
              return (ClientSettingsSection)group.Sections[clientSectionName];
          }
      
      
          ///<summary>
          /// return the section settings collection
          ///</summary>
          ///<returns></returns>
          public static System.Configuration.SettingElementCollection GetSettingsCollection(ClientSettingsSection section)
          {
              return section.Settings;
          }
      
          ///<summary>
          /// return the connectionStrings section collection
          ///</summary>
          ///<returns></returns>
          public static System.Configuration.SettingElementCollection ConnectionStringsCollection()
          {
              return ((ClientSettingsSection)SharedConfigSettings.GetSection("connectionStrings")).Settings;
          }
      
          ///<summary>
          /// A collection of all the UserSettings in a SettingElementCollection
          ///</summary>
          ///<returns></returns>
          public static SettingElementCollection UserSettings()
          {
              return
                  GetSettingsCollection(GetSettingsSection(GetSettingsSectionGroup(@"userSettings"),
                                                           @"MyAssembly.Properties.Settings"));
          }
      
          ///<summary>
          /// A collection of all the ApplicationSettings in a SettingElementCollection
          ///</summary>
          ///<returns></returns>
          public static SettingElementCollection ApplicationSettings()
          {
              return
                  GetSettingsCollection(GetSettingsSection(GetSettingsSectionGroup(@"applicationSettings"),
                                                           @"MyAssembly.Properties.Settings"));
          }
      

      然后,不幸的是,您仍然需要处理这些部分中设置集合中的 SettingElement 对象。每个都必须反序列化为属性类型,除非它是一个字符串,例如对于 applicationSettings SettingElement(不能在运行时动态更新):

      (锻炼者)

       var y = GetSettingsSection(GetSettingsSectionGroup(@"applicationSettings"), @"MyAssembly.Properties.Settings");
       var c = (y.Settings.Cast<SettingElement>().FirstOrDefault(s => s.Name == "WellKnownDirectories").Value).ValueXml
                      .InnerXml; // the setting as Xml
       var xs = new XmlSerializer(typeof(string[]));
       var strings = (string[])xs.Deserialize(new XmlTextReader(c, XmlNodeType.Element, null));
      
      foreach (string s in strings)
              {
                  Console.WriteLine(s);
              }
      

      对于字符串属性,它更容易(这个例子与上面的第一个例子本质上是多余的):

      var s = (y.Settings.Cast<SettingElement>().FirstOrDefault(s => s.Name == "MyUserSettingName").Value).ValueXml
                      .InnerText
      

      所有这些示例都使用了 applicationSettings。相同的方法可以与 userSettings 一起使用,可能会添加一些保存方法等,并且您确实需要跟踪(或多或少)多个配置文件中的哪些实际上正在播放 - 主文件、漫游文件或本地文件.

      我为什么要这样做?因为两个相关的应用程序和一个公共类库(或多个库)都需要使用由其中一个应用程序拥有的相同设置,其中设置是可视化管理的。有没有人以更好的方式解决这个问题?

      谢谢。

      【讨论】:

        【解决方案4】:

        您的连接字符串通常位于配置管理器的 ConnectionStrings 属性中。您应该能够通过其静态方法以更简单的方式进行访问。

        string myConnectionString = ConfigurationManager.ConnectionStrings["connectioStringName"];
        

        我认为您应该在 .config 文件中使用标签“AppSettings”而不是“ApplicationSettings”,以使 ConfigurationManager 能够通过 AppSettings 属性进行访问。

        我对 ConfigurationManager 的工作原理知之甚少,无法确保这会解决您的问题,但是重命名它并删除该自定义部分组应该可以让 AppSettings 正常工作。

        编辑 是的,ConfigurationManager 的 AppSettings 属性似乎访问了名为 在 .config 文件中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-14
          • 2020-10-26
          • 2016-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多