I have an IEnumerable<KeyValuePair<string,string>>, from which I would like, ideally, an anonymous object which has the keys as property names and the values as property values.
I’ve tried various selection expressions (none of which even compiled…) and an approach using ExpandoObject (see below), but without success. Is there a good way to do this? If possible, I’d like to avoid an extra explicit iteration over the collection (i.e. do it all with a LINQ statement of some sort).
This is what I’ve tried so far. I hope it also clarifies what I’m trying to do:
var kvps = getProps(); // returns IEnumerable<KeyValuePair<string,string>>
dynamic o = new ExpandoObject();
foreach (var kvp in kvps)
{
o.Add(kvp);
}
This is OK at compile time, but at runtime I get a YSOD stating ‘System.Dynamic.ExpandoObject’ does not contain a definition for ‘Add’ – I guess it works at compile time because o is dynamic, so the compiler can’t know if a method .Add() has been added to it since it was instantiated. The odd thing is, that on the MSDN documenation page for ExpandoObject .Add() is listed as one of several “explicitly implemented interface methods”.
It is not necessary for me to get this into a dynamic object – I just need to get something that has property names and values according to the keys and values of the key-value pairs.
Update: Well, this is embarrassing. Turns out this was something of an XY-problem too.
I’m trying to render this to JSON using the built-in features of ASP.NET MVC, by simply returning Json(data) in my controller. The answers all worked very well to do what I first asked, but when I pass this object as data I still don’t get what I want:
// What I get:
[
{ Key: 'firstkey', Value: 'FirstValue' },
{ Key: 'secondKey', Value: 'secondValue' }
]
// What I want:
{ firstKey: 'FirstValue', secondKey: 'secondValue' }
Apparently, an ExpandoObject with the relevant properties added didn’t cut it – it was cast to a dictionary before rendering…
ExpandoObjectexplicitly implementsIDictionary<string, object>– so you need to cast it to one first:Now you can use
oas you would expect:Interesting.
To do that, you serialize a dictionary, not an ExpandoObject. MVC 3’s JSON serializer already does that with a dictionary. All you have to do is convert your
IEnumerable<KeyValuePair<string, object>>to a dictionary:No dynamics required.