2009-08-05 4 views
5

я доступ к конфигурации моей новой сборки, как это:Получение 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. Где я могу найти свою коллекцию строк?

ответ

6

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

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

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

+0

OK. Я могу прочитать массив строк таким образом. Но строки исходят из по умолчанию, скомпилированного в сборку. Мне нужно иметь возможность добавлять, удалять и изменять строки в этой коллекции после развертывания сборки. Файл .Properties.Settings.Default не принимает изменения в файле .config. Имел ту же проблему со строками подключения, пока я не начал просматривать ConfigurationManager. –

+0

Возможно, вам необходимо получить доступ к методу ConfigurationManager: ConfigurationManager.GetSection ("applicationSettings"); , который должен вернуть объект, для которого вы хотите проанализировать – jkelley

+0

ConfigurationManager.GetSection ("applicationSettings") возвращает null –

1

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

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

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

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

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

2

AppSettings и ConnectionStrings - оба свойства, непосредственно доступные в ConfigurationManager.

Однако applicationSettings и UserSettings, которые соответствуют знакомым Settings.settings можно редактировать в настройках дизайнера VS, не так легко добраться. AppSettings is NOT так же, как 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; 
    } 

и другой пример (adaoted из многих примеров - спасибо всем мире):

///<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 (тот, который не может быть динамически обновляется во время выполнения):

(Тренажер)

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 

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

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

Спасибо.

2

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

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

будет выполнять столько с из необходимости XmlSerializer

Смежные вопросы