Получение StringCollection из AppSettings через менеджер конфигурации - PullRequest
5 голосов
/ 06 августа 2009

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

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

Ответы [ 4 ]

6 голосов
/ 06 августа 2009

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

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

EDIT:

Следующий код должен сработать

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

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

2 голосов
/ 23 мая 2012

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

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

достигнет такого же уровня без необходимости в XmlSerializer

2 голосов
/ 21 июля 2011

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, которые находятся в коллекции настроек в этих разделах. Каждый из них должен быть десериализован в свойство Type, если это не строка, например для ApplicationSettings SettingElement (который не может быть динамически обновлен во время выполнения):

(*) использование нагрузочных 1033 *

 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

Все эти примеры возились с настройками приложения. Тот же самый подход может работать с пользовательскими настройками с добавлением, вероятно, некоторых методов сохранения и т. Д., И вам необходимо отслеживать (более или менее), какой из нескольких конфигурационных файлов в действительности находится в игре - основной, перемещаемый или локальный .

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

Спасибо.

1 голос
/ 06 августа 2009

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

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

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

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

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

...