Получение 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)


arrow_upward
6
arrow_downward

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

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

arrow_upward
3
arrow_downward

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

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

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

person Kevin Stout    schedule 23.05.2012

arrow_upward
2
arrow_downward

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

arrow_upward
1
arrow_downward

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

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

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

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

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

person jkelley    schedule 05.08.2009