Multiple values for a single config key

70,857

Solution 1

Try

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

And

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

Solution 2

The config file treats each line like an assignment, which is why you're only seeing the last line. When it reads the config, it assigns your key the value of "A", then "B", then "C", and since "C" is the last value, it's the one that sticks.

as @Kevin suggests, the best way to do this is probably a value whose contents are a CSV that you can parse apart.

Solution 3

I know I'm late but i found this solution and it works perfectly so I just want to share.

It's all about defining your own 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"]; }
        }
    }
}

And in the app.config just use your new section:

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

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

and when retrieving data just like this :

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

Finally thanks to the author of the original post

Solution 4

What you want to do is not possible. You either have to name each key differently, or do something like value="A,B,C" and separate out the different values in code string values = value.split(',').

It will always pick up the value of the key which was last defined (in your example C).

Solution 5

I use naming convention of the keys and it works like a charm

<?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
    }
}
Share:
70,857
Daniel Schierbeck
Author by

Daniel Schierbeck

I'm an enthusiastic Python, Ruby and Rails developer, with additional experience in PHP and general web stuff (CSS, HTML and JavaScript.)

Updated on September 23, 2020

Comments

  • Daniel Schierbeck
    Daniel Schierbeck over 3 years

    I'm trying to use ConfigurationManager.AppSettings.GetValues() to retrieve multiple configuration values for a single key, but I'm always receiving an array of only the last value. My appsettings.config looks like

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

    and I'm trying to access with

    ConfigurationManager.AppSettings.GetValues("mykey");
    

    but I'm only getting { "C" }.

    Any ideas on how to solve this?

  • Yuck
    Yuck almost 11 years
    So what's the point of ConfigurationManager.AppSettings.GetValues() then?
  • user3036342
    user3036342 about 9 years
    ConfigurationManager.ConnectionStrings gives you the ability to loop through a list which negates any and all answers to this question (I know it's not connection string per say, but you can use it as such)
  • fusi
    fusi about 8 years
    @Yuck one questions the point of the underlying NameValueCollection class - which supports multiple values per key, but doesn't actually let you set more than one per key (AppSettings must internally use the set indexer) - this is the true cause of the issue, rather than GetValues() only returning a single value.
  • Ajaya Nayak
    Ajaya Nayak about 8 years
    Thanks CubeJockey for reallignment.
  • Tinoy Jameson
    Tinoy Jameson over 6 years
    If there is only single value, any character not found error occurs?
  • Chandy Kunhu
    Chandy Kunhu almost 6 years
    it is a good one to have a standard retrieval and by specifying key and value
  • Jahaziel
    Jahaziel about 3 years
    I think this is the cleanest solution. It also allows for values that may already contain many of the usual separator characters. I implemented it and solved my issue, and I don't have to worry that some day, a value may be required that uses that one particular separator.