NameValueCollection's GetValues does not return multiple entries

  • Thread starter Thread starter Vagif Abilov
  • Start date Start date
V

Vagif Abilov

When I use AppSettings and try to retrieve multiple values associated with a
single key, I only get the last value. E.g. if I have in my config


<appSettings>
<add key="Key" value="Value1" />
<add key="Key" value="Value2" />
</appSettings>

then attempt to read both values by using AppSettings.GetValues("Key") gives
only "Value2".

This is not what's written in .NET Framework documentation which says:

"NameValueCollection collection is based on the NameObjectCollectionBase
class. However, unlike the NameObjectCollectionBase, this class stores
multiple string values under a single key."

And the whole purpose og GetValues is to retrieve multiple values, ulike an
indexer that only returns a single value. It does return a string array, but
only with a single value.

What can be wrong?

Vagif Abilov

vagif @ online.no
 
Hello Vagif,

A key is supposed to be unique. I think what you are after is this:

<add key="Key" value="Value1,Value2" />

The NameValueCollection returns a string array based on a string split on
','.
 
The strange thing is that if I use your format: <add key="Key"
value="Value1,Value2" />
then GetValues() returns an array that contains only the first value
("Value1").

I also don't think it should work that way. NameValueCollection.Add() method
(unlike Set) _adds_ another value to an existing key if it already exists,
so why they implemented it differently in AppSettingReader?

Vagif
 
Hello Vagif,

Can you post a small example project that demonstrates the problem you are
having?
 
Yes sure. Actually it's just to paste the following code in a simple
console-based application:

class Class1
{
[STAThread]
static void Main(string[] args)
{
string[] values;
values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key1");
foreach(string s in values)
Console.WriteLine(s);

values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key2");
foreach(string s in values)
Console.WriteLine(s);
}
}

And then create config file with the following contents:


<appSettings>
<add key="Key1" value="Value1,Value2" />
<add key="Key2" value="Value1" />
<add key="Key2" value="Value2" />
</appSettings>

For key1 I am getting an array with a single string "Value1,Value2", for
key2 it contains a single string "Value2". And according to the
documentation I should be able to add and retrieve multiple values per key -
this is the main difference between NameValueCollection and
NameObjectCollectionBase.

Vagif
 
Hello Vagif,

I think I finally see what you mean. You are expecting Key2 to return both
values, when its only returning one.

This is probably a limitation in the NameValueSectionHandler, although you
could get around it using the syntax that you use for Key1.

--
Matt Berther
http://www.mattberther.com
Yes sure. Actually it's just to paste the following code in a simple
console-based application:

class Class1
{
[STAThread]
static void Main(string[] args)
{
string[] values;
values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key1
");
foreach(string s in values)
Console.WriteLine(s);
values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key2
");
foreach(string s in values)
Console.WriteLine(s);
}
}

And then create config file with the following contents:

<appSettings>
<add key="Key1" value="Value1,Value2" />
<add key="Key2" value="Value1" />
<add key="Key2" value="Value2" />
</appSettings>
For key1 I am getting an array with a single string "Value1,Value2",
for key2 it contains a single string "Value2". And according to the
documentation I should be able to add and retrieve multiple values per
key - this is the main difference between NameValueCollection and
NameObjectCollectionBase.

Vagif

Hello Vagif,

Can you post a small example project that demonstrates the problem
you are having?
 
Actually I didn't expect that. I really mean Key1 should return an array
consisting of two strings - and it just returns one. This is what I found
inconsistent.

Vagif

Matt Berther said:
Hello Vagif,

I think I finally see what you mean. You are expecting Key2 to return both
values, when its only returning one.

This is probably a limitation in the NameValueSectionHandler, although you
could get around it using the syntax that you use for Key1.

--
Matt Berther
http://www.mattberther.com
Yes sure. Actually it's just to paste the following code in a simple
console-based application:

class Class1
{
[STAThread]
static void Main(string[] args)
{
string[] values;
values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key1
");
foreach(string s in values)
Console.WriteLine(s);
values =
System.Configuration.ConfigurationSettings.AppSettings.GetValues("Key2
");
foreach(string s in values)
Console.WriteLine(s);
}
}

And then create config file with the following contents:

<appSettings>
<add key="Key1" value="Value1,Value2" />
<add key="Key2" value="Value1" />
<add key="Key2" value="Value2" />
</appSettings>
For key1 I am getting an array with a single string "Value1,Value2",
for key2 it contains a single string "Value2". And according to the
documentation I should be able to add and retrieve multiple values per
key - this is the main difference between NameValueCollection and
NameObjectCollectionBase.

Vagif

Hello Vagif,

Can you post a small example project that demonstrates the problem
you are having?

--
Matt Berther
http://www.mattberther.com
The strange thing is that if I use your format: <add key="Key"
value="Value1,Value2" />
then GetValues() returns an array that contains only the first value
("Value1").
I also don't think it should work that way.
NameValueCollection.Add()
method (unlike Set) _adds_ another value to an existing key if it
already exists, so why they implemented it differently in
AppSettingReader?
Vagif


Hello Vagif,

A key is supposed to be unique. I think what you are after is this:

<add key="Key" value="Value1,Value2" />

The NameValueCollection returns a string array based on a string
split on ','.

--
Matt Berther
http://www.mattberther.com
When I use AppSettings and try to retrieve multiple values
associated with a single key, I only get the last value. E.g. if I
have in my config

<appSettings>
<add key="Key" value="Value1" />
<add key="Key" value="Value2" />
</appSettings>
then attempt to read both values by using
AppSettings.GetValues("Key")
gives only "Value2".
This is not what's written in .NET Framework documentation which
says:
"NameValueCollection collection is based on the
NameObjectCollectionBase class. However, unlike the
NameObjectCollectionBase, this class stores multiple string values
under a single key."

And the whole purpose og GetValues is to retrieve multiple values,
ulike an indexer that only returns a single value. It does return
a string array, but only with a single value.

What can be wrong?

Vagif Abilov

vagif @ online.no
 
I too am confised by the documentation.
MSDN States:

Overloads Public Overridable Function GetValues( _
ByVal name As String _
) As String()

Overloads Public Overridable Function Get( _
ByVal name As String _
) As String

It could not be more plain than that. Yet I get the same results as
Vagif.

It appears that either I am not entering the app.config data correctly
or that the get values function does not act as I would expect.

anyone else have any ideas how to save an array of strings in
app.config?


Thanks
 
Hi,

I've been pounding on a similar issue for a couple of hours and ran into
your posts.

I was finally successfully found a reference at:
http://www.o-xml.org/projects/mlml/cli/System.Collections.Specialized.Na
meValueCollection.html

You need to scroll down a little pass constructor to get to the first
public virtual method Add(string name, string value)

I quote: "If the specified key already exists in the current instance,
the specified value is added to the existing comma-separated list of
values associated with the same key. Attempting to assign the same value
to an existing key adds a new value to that key, thus providing two (or
more) copies of the same value associated with the key."

I've put together a small sample to demonstrate:

public class Class2 {
[STAThread]
static void Main(string[] args) {
NameValueCollection nv = new NameValueCollection();
NameValueCollection nvMulti = new NameValueCollection();

Random r = new Random();
for (int i = 0; i < 3; i++)
nv.Add("itm " + i, r.Next(50).ToString());
// Multi Values NameValueCollection
for (int i = 0; i < 3; i++) {
nvMulti.Add("t" + i, r.Next(1000).ToString()); // add 1st value
nvMulti.Add("t" + i, r.Next(1000).ToString()); // add 2nd value
nvMulti.Add("t" + i, r.Next(1000).ToString()); // add 3rd value
}

for (int i = 0; i < nv.Count; i++)
Console.WriteLine("item[`{0}`] = {1}", nv.GetKey(i),
nv.GetValues(i)[0]);

for (int i = 0; i < nv.Count; i++) {
System.Text.StringBuilder vals = new
System.Text.StringBuilder();
for (int j = 0; j < nvMulti.GetValues(i).Length; j++) {
vals.Append(nvMulti.GetValues(i)[j] + "~");
}
Console.WriteLine("item[`{0}`] = {1}", nvMulti.GetKey(i), vals);
Console.WriteLine("item[`{0}`] = {1}", nvMulti.GetKey(i),
nvMulti.GetValues(i)[0]);
Console.WriteLine("item[`{0}`] = {1}", nvMulti.GetKey(i),
nvMulti.Get(i));
}
}
}

The result is quite interesting:
When adding more than one name/value pair using the same name to a
NameValueCollection, it will create the 'Array' of values (it's actually
is ArrayList).
Printing out the value using Get(i), C# prints comma separated values.
For example, 123,456,789
GetValues(i).Length will print out 3 for this sample which means 3
item in the array.

Good luck, Jeff
 
Back
Top