2009-08-05 12 views
5

sto richiama la configurazione del mio montaggio in questo modo:Ottenere uno StringCollection fuori AppSettings tramite il gestore di configurazione

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

Il mio file .config contiene una sezione come questo

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

posso leggere con successo il stringhe di connessione comprese le modifiche se modifico il file .config. Quindi, so di essere collegato al file corretto. Ma non riesco a trovare quella raccolta di stringhe all'interno dell'oggetto appSettings. Non si trova in .Settings KeyValueConfigurationCollection. Dove trovo la mia collezione di stringhe?

risposta

6

Si dovrebbe accedere alle voci della collezione utilizza questa sintassi più semplice

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

EDIT:

Il seguente codice dovrebbe fare il trucco

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

Ci può essere un modo più breve , ma questo funziona per me.

+0

OK. Posso leggere l'array di stringhe in questo modo. Ma le stringhe provengono dal default compilato nell'assembly. Devo essere in grado di aggiungere, rimuovere e modificare stringhe in quella raccolta dopo che l'assembly è stato distribuito. Il .Properties.Settings.Default non rileva modifiche nel file .config. Ha avuto lo stesso problema con le stringhe di connessione fino a quando ho iniziato a passare attraverso il ConfigurationManager. –

+0

Probabilmente è necessario accedere al metodo di ConfigurationManager: ConfigurationManager.GetSection ("applicationSettings"); che dovrebbe restituire l'oggetto per il quale si desidera analizzare – jkelley

+0

ConfigurationManager.GetSection ("applicationSettings") restituisce null –

1

Le stringhe di connessione sono in genere all'interno della proprietà ConnectionStrings del Configuration Manager. Dovresti essere in grado di accedere in modo molto più semplice attraverso il suo metodo statico.

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

Credo che si dovrebbe utilizzare il tag "AppSettings" invece di "ApplicationSettings" nel file .config per consentire ConfigurationManager per accedere tramite la proprietà AppSettings.

Non so abbastanza su come funziona ConfigurationManager per essere sicuro che questo risolva il problema, ma rinominarlo e rimuovere quel gruppo di sezioni personalizzato dovrebbe consentire ad AppSettings di funzionare correttamente.

Modifica Sì, sembra che la proprietà AppSettings di ConfigurationManager accede alla sezione denominata nel file config.

2

AppSettings e ConnectionString sono entrambe proprietà direttamente disponibili su ConfigurationManager.

Tuttavia, ApplicationSettings e UserSettings, che corrispondono ai familiari Settings.settings è possibile modificare le impostazioni nel progettista VS, non sono così facili da raggiungere. AppSettings è NON uguale a applicationSettings che si trova in una sezione completamente diversa del file di configurazione in uso.

è necessario utilizzare il metodo mineraria sopra o una variante per arrivare al ApplicationSettings e UserSettings. Inoltre, le impostazioni dell'applicazione si aggiorneranno solo la prossima volta che avvierai l'applicazione, se sarai addirittura in grado di scrivere su di esse in fase di runtime.

Per esempio (cribbed da altrove - grazie):

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

e per un altro esempio (adaoted da molti esempi - grazie al mondo):

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

Poi, purtroppo devono ancora occuparsi degli oggetti SettingElement che si trovano nella raccolta delle impostazioni in queste sezioni. Ognuno deve deserializzare al tipo di proprietà a meno che non sia una stringa, ad es. un ApplicationSettings SettingElement (che non può essere aggiornata dinamicamente durante l'esecuzione):

(ginnico)

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

Per una proprietà stringa è più facile (questo esempio è essenzialmente ridondante con il primo sopra):

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

Tutti questi esempi hanno giocato con le impostazioni dell'applicazione. Lo stesso approccio può funzionare con userSettings con l'aggiunta di probabilmente alcuni metodi di salvataggio e così via, e devi tenere traccia (più o meno) di quale dei molti molti file di configurazione sono effettivamente in riproduzione: main, roaming o locale .

Perché sto facendo questo? Poiché due applicazioni correlate e una libreria di classi comuni (o librerie) devono tutte utilizzare le stesse impostazioni di proprietà di una delle applicazioni in cui le impostazioni sono gestite visivamente. Qualcuno ha risolto questo in un modo migliore?

Grazie.

2

se si tratta di uno StringCollection si sta cercando di estrarre dalle impostazioni

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

compirà tanto con la necessità di XmlSerializer

Problemi correlati