Получение StringCollection из AppSettings через диспетчер конфигурации

Я получаю доступ к конфигурации моей сборки следующим образом:

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. Где я могу найти свою коллекцию струн?


person Rodney Schuler    schedule 05.08.2009    source источник


Ответы (4)


Вы должны получить доступ к элементам в коллекции, используя этот более простой синтаксис

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

Может быть, есть более короткий путь, но это работает для меня.

person Michael A. McCloskey    schedule 05.08.2009
comment
В ПОРЯДКЕ. Я могу читать массив строк таким образом. Но строки по умолчанию скомпилированы в сборку. Мне нужно иметь возможность добавлять, удалять и изменять строки в этой коллекции после развертывания сборки. .Properties.Settings.Default не вносит изменения в файл .config. У меня была такая же проблема со строками подключения, пока я не начал просматривать ConfigurationManager. - person Rodney Schuler; 06.08.2009
comment
Вам, вероятно, потребуется получить доступ к методу ConfigurationManager: ConfigurationManager.GetSection(applicationSettings); который должен возвращать объект, который вы хотите проанализировать - person jkelley; 06.08.2009
comment
ConfigurationManager.GetSection(applicationSettings) возвращает значение null - person Rodney Schuler; 06.08.2009
comment
Пожалуйста, обратитесь к моему редактированию. Он находит путь к соответствующему элементу XML в файле конфигурации, а затем десериализует его, используя стандартные вызовы сериализации Xml. - person Michael A. McCloskey; 06.08.2009
comment
Смотрите ответ @Kevin Stout ниже. Это гораздо более простое и легко реализуемое решение этой проблемы. Обратите внимание, что его ответ приходит примерно на 2,5 года позже исходного ответа, но выглядит как лучший ответ, по крайней мере, для VS2013. - person STLDev; 01.09.2015

если это StringCollection, который вы пытаетесь извлечь из настроек

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

сделает столько же без необходимости в XmlSerializer

person Kevin Stout    schedule 23.05.2012

AppSettings и ConnectionStrings являются свойствами, доступными непосредственно в ConfigurationManager.

Однако applicationSettings и userSettings, которые соответствуют знакомым Settings.settings, которые вы можете редактировать в дизайнере настроек VS, не так просто получить. в. AppSettings НЕ совпадает с applicationSettings, который находится в совершенно другом разделе используемого файла конфигурации.

Чтобы получить applicationSettings и userSettings, вы должны использовать описанный выше подход или его вариант. Кроме того, 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 (который не может быть динамически обновлен во время выполнения):

(тренажер)

 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 с добавлением, возможно, некоторых методов сохранения и т. Д., И вам нужно отслеживать (более или менее), какой из нескольких файлов конфигурации фактически используется - основной, перемещаемый или локальный. .

Почему я это делаю? Потому что два связанных приложения и общая библиотека классов (или библиотеки) должны использовать одни и те же параметры, принадлежащие одному из приложений, где параметры управляются визуально. Кто-нибудь решил это лучше?

Спасибо.

person AllenM    schedule 21.07.2011

Строки подключения обычно находятся внутри свойства ConnectionStrings диспетчера конфигурации. Вы должны иметь возможность получить доступ гораздо более простым способом через его статический метод.

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

Я считаю, что вы должны использовать тег «AppSettings» вместо «ApplicationSettings» в файле .config, чтобы разрешить ConfigurationManager доступ через свойство AppSettings.

Я не знаю достаточно о том, как работает ConfigurationManager, чтобы быть уверенным, что это решит вашу проблему, но переименование его и удаление этой группы настраиваемых разделов должно позволить AppSettings работать правильно.

Изменить Да, похоже, свойство AppSettings ConfigurationManager обращается к разделу, указанному в файле .config.

person jkelley    schedule 05.08.2009