2010-05-12 14 views
34

Sto tentando di utilizzare ConfigurationManager.AppSettings.GetValues() per recuperare più valori di configurazione per una singola chiave, ma ricevo sempre una matrice solo dell'ultimo valore. Il mio appsettings.config sembraPiù valori per una singola chiave di configurazione

<add key="mykey" value="A"/> 
<add key="mykey" value="B"/> 
<add key="mykey" value="C"/> 

e sto cercando di accedere con

ConfigurationManager.AppSettings.GetValues("mykey"); 

ma sto ottenendo soltanto { "C" }.

Qualche idea su come risolvere questo?

risposta

37

Prova

<add key="mykey" value="A,B,C"/> 

E

string[] mykey = ConfigurationManager.AppSettings["mykey"].Split(','); 
+13

Allora, qual è il punto di 'ConfigurationManager.AppSettings.GetValues ​​() 'allora? – Yuck

+0

@Yuck one interroga il punto della classe NameValueCollection sottostante, che supporta più valori per chiave, ma in realtà non consente di impostare più di una chiave (AppSettings deve utilizzare internamente l'indicizzatore dell'insieme) - questa è la vera causa del problema, piuttosto che GetValues ​​() restituisce solo un singolo valore. – fusi

+0

Se è presente un solo valore, si verifica un errore di carattere non trovato? –

6

Quello che vuoi fare non è possibile. È necessario assegnare un nome a ciascun tasto in modo diverso oppure eseguire un'operazione come value = "A, B, C" e separare i diversi valori nel codice string values = value.split(',').

Riporterà sempre il valore della chiave che è stata definita l'ultima volta (nell'esempio C).

9

il file di configurazione tratta ogni linea come un incarico, che è il motivo per cui si sta vedendo solo l'ultima riga. Quando legge la configurazione, assegna alla chiave il valore di "A", quindi "B", quindi "C", e poiché "C" è l'ultimo valore, è quello che si attacca.

come suggerisce @Kevin, il modo migliore per farlo è probabilmente un valore il cui contenuto è un CSV che è possibile analizzare separatamente.

2

Poiché il metodo ConfigurationManager.AppSettings.GetValues() non funziona, ho usato la seguente soluzione per ottenere un effetto simile, ma con la necessità di suffisso i tasti con indici unici.

var name = "myKey"; 
var uniqueKeys = ConfigurationManager.AppSettings.Keys.OfType<string>().Where(
    key => key.StartsWith(name + '[', StringComparison.InvariantCultureIgnoreCase) 
); 
var values = uniqueKeys.Select(key => ConfigurationManager.AppSettings[key]); 

Ciò corrisponderà tasti come myKey[0] e myKey[1].

+0

ConfigurationManager.ConnectionStrings ti dà la possibilità di scorrere un elenco che nega tutte le risposte a questa domanda (so che non è una stringa di connessione per dire, ma puoi usarlo come tale) – user3036342

9

So che sono in ritardo ma ho trovato questa soluzione e funziona perfettamente, quindi voglio solo condividere.

E 'tutto su come definire il proprio ConfigurationElement

namespace Configuration.Helpers 
{ 
    public class ValueElement : ConfigurationElement 
    { 
     [ConfigurationProperty("name", IsKey = true, IsRequired = true)] 
     public string Name 
     { 
      get { return (string) this["name"]; } 
     } 
    } 

    public class ValueElementCollection : ConfigurationElementCollection 
    { 
     protected override ConfigurationElement CreateNewElement() 
     { 
      return new ValueElement(); 
     } 


     protected override object GetElementKey(ConfigurationElement element) 
     { 
      return ((ValueElement)element).Name; 
     } 
    } 

    public class MultipleValuesSection : ConfigurationSection 
    { 
     [ConfigurationProperty("Values")] 
     public ValueElementCollection Values 
     { 
      get { return (ValueElementCollection)this["Values"]; } 
     } 
    } 
} 

E in app.config basta usare la tua nuova sezione:

<configSections> 
    <section name="PreRequest" type="Configuration.Helpers.MultipleValuesSection, 
    Configuration.Helpers" requirePermission="false" /> 
</configSections> 

<PreRequest> 
    <Values> 
     <add name="C++"/> 
     <add name="Some Application"/> 
    </Values> 
</PreRequest> 

e quando il recupero dei dati, proprio come questo:

var section = (MultipleValuesSection) ConfigurationManager.GetSection("PreRequest"); 
var applications = (from object value in section.Values 
        select ((ValueElement)value).Name) 
        .ToList(); 

Infine, grazie all'autore dell'originale post

0

Ecco la soluzione completa: codice in aspx.cs

namespace HelloWorld 
{ 
    public partial class _Default : Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      UrlRetrieverSection UrlAddresses = (UrlRetrieverSection)ConfigurationManager.GetSection("urlAddresses"); 
     } 
    } 

    public class UrlRetrieverSection : ConfigurationSection 
    { 
     [ConfigurationProperty("", IsDefaultCollection = true,IsRequired =true)] 
     public UrlCollection UrlAddresses 
     { 
      get 
      { 
       return (UrlCollection)this[""]; 
      } 
      set 
      { 
       this[""] = value; 
      } 
     } 
    } 


    public class UrlCollection : ConfigurationElementCollection 
    { 
     protected override ConfigurationElement CreateNewElement() 
     { 
      return new UrlElement(); 
     } 
     protected override object GetElementKey(ConfigurationElement element) 
     { 
      return ((UrlElement)element).Name; 
     } 
    } 

    public class UrlElement : ConfigurationElement 
    { 
     [ConfigurationProperty("name", IsRequired = true, IsKey = true)] 
     public string Name 
     { 
      get 
      { 
       return (string)this["name"]; 
      } 
      set 
      { 
       this["name"] = value; 
      } 
     } 

     [ConfigurationProperty("url", IsRequired = true)] 
     public string Url 
     { 
      get 
      { 
       return (string)this["url"]; 
      } 
      set 
      { 
       this["url"] = value; 
      } 
     } 

    } 
} 

E nel web config

<configSections> 
    <section name="urlAddresses" type="HelloWorld.UrlRetrieverSection" /> 
</configSections> 
<urlAddresses> 
    <add name="Google" url="http://www.google.com" /> 
    <add name="Yahoo" url="http://www.yahoo.com" /> 
    <add name="Hotmail" url="http://www.hotmail.com/" /> 
</urlAddresses> 
+0

Grazie a CubeJockey per l'allineamento. –

0

mio prendere sulla risposta di JJS: Config File:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="List1" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
    <section name="List2" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> 
    </configSections> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> 
    </startup> 
    <List1> 
    <add key="p-Teapot" /> 
    <add key="p-drongo" /> 
    <add key="p-heyho" /> 
    <add key="p-bob" /> 
    <add key="p-Black Adder" /> 
    </List1> 
    <List2> 
    <add key="s-Teapot" /> 
    <add key="s-drongo" /> 
    <add key="s-heyho" /> 
    <add key="s-bob"/> 
    <add key="s-Black Adder" /> 
    </List2> 

</configuration> 

codice per recuperare in string []

private void button1_Click(object sender, EventArgs e) 
    { 

     string[] output = CollectFromConfig("List1"); 
     foreach (string key in output) label1.Text += key + Environment.NewLine; 
     label1.Text += Environment.NewLine; 
     output = CollectFromConfig("List2"); 
     foreach (string key in output) label1.Text += key + Environment.NewLine; 
    } 
    private string[] CollectFromConfig(string key) 
    { 
     NameValueCollection keyCollection = (NameValueCollection)ConfigurationManager.GetSection(key); 
     return keyCollection.AllKeys; 
    } 

IMO, è semplice a s sta per arrivare. Sentitevi liberi di dimostrare il torto :)

0

Io uso convenzione di denominazione delle chiavi e funziona come un fascino

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <section name="section1" type="System.Configuration.NameValueSectionHandler"/> 
    </configSections> 
    <section1> 
    <add key="keyname1" value="value1"/> 
    <add key="keyname21" value="value21"/> 
    <add key="keyname22" value="value22"/> 
    </section1> 
</configuration> 

var section1 = ConfigurationManager.GetSection("section1") as NameValueCollection; 
for (int i = 0; i < section1.AllKeys.Length; i++) 
{ 
    //if you define the key is unique then use == operator 
    if (section1.AllKeys[i] == "keyName1") 
    { 
     // process keyName1 
    } 

    // if you define the key as a list, starting with the same name, then use string StartWith function 
    if (section1.AllKeys[i].Startwith("keyName2")) 
    { 
     // AllKeys start with keyName2 will be processed here 
    } 
} 
Problemi correlati