2009-08-05 16 views
5

estoy accediendo a la configuración de mi montaje de la siguiente manera:Conseguir un StringCollection de AppSettings a través del administrador de configuración

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

Mi archivo .config contiene una sección como esta

<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> 

puedo leer con éxito el Cadenas de conexión, incluidos los cambios, si edito el archivo .config. Entonces, sé que estoy conectado al archivo correcto. Pero no puedo encontrar esa colección de cadenas dentro del objeto appSettings. No se encuentra en. Settings KeyValueConfigurationCollection. ¿Dónde encuentro mi colección de cuerdas?

Respuesta

6

Usted debe tener acceso a los elementos de la colección, con esta sintaxis más simple

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

EDIT:

El siguiente código debe hacer el truco

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

Puede haber un camino más corto , pero esto funciona para mí.

+0

OK. Puedo leer la matriz de cadenas de esa manera. Pero, las cadenas provienen del valor predeterminado compilado en el conjunto. Necesito poder agregar, quitar y cambiar cadenas en esa colección después de desplegar el ensamblado. The .Properties.Settings.Default no recupera las ediciones del archivo .config. Tuve el mismo problema con las cadenas de conexión hasta que comencé a utilizar el ConfigurationManager. –

+0

Probablemente necesite acceder al método de ConfigurationManager: ConfigurationManager.GetSection ("applicationSettings"); que debería devolver el objeto que está buscando analizar – jkelley

+0

ConfigurationManager.GetSection ("applicationSettings") devuelve nulo –

1

Las cadenas de conexión normalmente están dentro de la propiedad ConnectionStrings del administrador de configuración. Debería poder acceder de una manera mucho más simple a través de su método estático.

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

creo que debe utilizar la etiqueta "AppSettings" en lugar de "ApplicationSettings" en el archivo .config para que el ConfigurationManager acceder a través de la propiedad AppSettings.

No sé lo suficiente acerca de cómo funciona ConfigurationManager para estar seguro de que esto resolverá su problema, pero cambiarle el nombre y eliminar ese grupo de sección personalizado debería permitir que AppSettings funcione correctamente.

Editar Sí, parece que la propiedad AppSettings de ConfigurationManager accede a la sección denominada en el archivo .config.

2

AppSettings y ConnectionStrings son propiedades directamente disponibles en el ConfigurationManager.

Sin embargo, applicationSettings y usersettings, que corresponden a los familiares Settings.settings se pueden editar en el diseñador de configuración VS, no son tan fáciles de alcanzar. AppSettings es NOT igual que applicationSettings que se encuentra en una sección completamente diferente del archivo de configuración en uso.

debe utilizar el enfoque de la minería por encima o por una variante para llegar a applicationSettings y usersettings. Además, el applicationSettings solo se actualizará la próxima vez que inicie la aplicación, incluso si puede escribir en el tiempo de ejecución.

Por ejemplo (cribbed de otro lugar - gracias):

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

y para otro ejemplo (adaoted de muchos ejemplos - gracias al mundo):

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

Entonces, por desgracia, todavía tiene que tratar con los objetos SettingElement que están en la colección de configuraciones en estas secciones. Cada uno tiene que deserializarse a la propiedad Tipo a menos que sea una cadena, p. para una SettingElement applicationSettings (uno que no se puede actualizar dinámicamente en tiempo de ejecución):

(ejercitador)

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

Para una propiedad de cadena es más fácil (este ejemplo es esencialmente redundante con el primero más arriba):

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

Todos estos ejemplos tocaron con applicationSettings. El mismo enfoque puede funcionar con userSettings con la adición de probablemente algunos métodos de guardado, y así sucesivamente, y necesita hacer un seguimiento (más o menos) de cuáles de los muchos archivos de configuración están realmente en funcionamiento: principal, roaming o local. .

¿Por qué estoy haciendo esto? Debido a que dos aplicaciones relacionadas y una biblioteca de clases común (o bibliotecas) necesitan usar la misma configuración que posee una de las aplicaciones donde la configuración se administra visualmente. ¿Alguien ha resuelto esto de una mejor manera?

Gracias.

2

si es un StringCollection que está intentando extraer de la configuración

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

va a lograr tanto con la necesidad de XmlSerializer

Cuestiones relacionadas