2010-05-12 12 views
34

Ich versuche ConfigurationManager.AppSettings.GetValues() zu verwenden, um mehrere Konfigurationswerte für einen einzelnen Schlüssel abzurufen, aber ich erhalte immer ein Array nur des letzten Werts. Meine appsettings.config sieht aus wieMehrere Werte für einen einzigen Config-Schlüssel

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

und ich versuche mit

ConfigurationManager.AppSettings.GetValues("mykey"); 

zugreifen, aber ich bin nur { "C" } bekommen.

Irgendwelche Ideen, wie man das löst?

Antwort

37

Versuchen

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

Und

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

Also, was der Punkt 'ConfigurationManager.AppSettings.GetValues ​​ist () 'dann? – Yuck

+0

@Yuck fragt den Punkt der zugrundeliegenden NameValueCollection-Klasse ab - die mehrere Werte pro Schlüssel unterstützt, aber nicht mehr als einen pro Schlüssel festlegen kann (AppSettings muss intern den Set-Indexer verwenden) - dies ist die wahre Ursache des Ausgabe, anstatt GetValues ​​() nur einen einzelnen Wert zurückgeben. – fusi

+0

Wenn nur ein einzelner Wert vorhanden ist, tritt ein beliebiger nicht gefundener Fehler auf? –

6

Was Sie tun möchten, ist nicht möglich. Sie müssen entweder jeden Schlüssel anders benennen oder etwas wie value = "A, B, C" machen und die verschiedenen Werte im Code string values = value.split(',') trennen.

Es wird immer den Wert des Schlüssels abholen, der zuletzt definiert wurde (in Ihrem Beispiel C).

9

Die Konfigurationsdatei behandelt jede Zeile wie eine Zuordnung, weshalb Sie nur die letzte Zeile zu sehen sind ist. Wenn es die Konfiguration liest, weist es Ihrem Schlüssel den Wert von "A", dann "B", dann "C" zu, und da "C" der letzte Wert ist, ist es derjenige, der haftet.

als @Kevin schlägt vor, der beste Weg, dies zu tun ist wahrscheinlich ein Wert, dessen Inhalt eine CSV, die Sie auseinander teilen können.

2

Da die ConfigurationManager.AppSettings.GetValues() Methode nicht funktioniert, habe ich die folgende Abhilfe zu erhalten, eine ähnliche Wirkung, aber mit der Notwendigkeit, verwenden den Schlüssel Suffix mit eindeutige Indizes.

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

Dies wird Tasten wie myKey[0] und myKey[1] entsprechen.

+0

ConfigurationManager.ConnectionStrings gibt Ihnen die Möglichkeit, eine Liste zu durchlaufen, die alle Antworten auf diese Frage negiert (ich weiß, dass es keine Verbindungszeichenfolge ist, aber Sie können sie als solche verwenden) – user3036342

9

Ich weiß, ich bin spät, aber ich fand diese Lösung und es funktioniert perfekt, also möchte ich nur teilen.

Es geht um Ihre eigene Definition von 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"]; } 
     } 
    } 
} 

Und in der app.config gerade Ihren neuen Abschnitt verwenden:

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

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

und wenn Daten wie diese abrufen:

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

Endlich dank dem Autor des Originals post

0

Hier ist die vollständige Lösung: Code 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; 
      } 
     } 

    } 
} 

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

Danke CubeJockey für Neuverteilung. –

0

Mein Nehmen auf JJS Antwort: Config-Datei:

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

-Code in Zeichenfolge abrufen []

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, das ist so einfach s wird es bekommen. Fühlen Sie sich frei, mich zu beweisen falsch :)

0

I Konvention der Schlüssel verwenden benennen und es wirkt wie ein Zauber

<?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 
    } 
} 
Verwandte Themen