32

I have a dynamic object that looks like this,

 {
    "2" : "foo",
    "5" : "bar",
    "8" : "foobar"
 }

How can I convert this to a dictionary?

Wasif Hossain
  • 3,900
  • 1
  • 18
  • 20
Kristian Nissen
  • 1,153
  • 2
  • 11
  • 29
  • 2
    This looks like JSON. Are you looking for JSON *deserialization* into a `Dictionary`? – Ondrej Tucny Feb 27 '14 at 09:34
  • 1
    You can use Linq Group method. Look here: http://code.msdn.microsoft.com/LINQ-to-DataSets-Grouping-c62703ea – mike00 Feb 27 '14 at 09:34
  • what object is it? JSON string? or JSON object? or List of KeyValuePair? or something else?? – Avishek Feb 27 '14 at 09:37
  • @OndrejTucny Actually this is a product of a JSON deserilization. Done like this: Dictionary values = JsonConvert.DeserializeObject>(json) The "json" in the question is the value that was stuffed into my dictionary – Kristian Nissen Feb 27 '14 at 09:40

9 Answers9

49

You can fill the dictionary using reflection:

public Dictionary<String, Object> Dyn2Dict(dynamic dynObj)
{
     var dictionary = new Dictionary<string, object>();
     foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dynObj))
     {
        object obj = propertyDescriptor.GetValue(dynObj);
        dictionary.Add(propertyDescriptor.Name, obj);
     }
     return dictionary;
}
digEmAll
  • 56,430
  • 9
  • 115
  • 140
ema
  • 5,668
  • 1
  • 25
  • 31
42

You can use a RouteValueDictionary to convert a C# object to a dictionary. See: RouteValueDictionary Class - MSDN. It converts object properties to key-value pairs.

Use it like this:

var toBeConverted = new {
    foo = 2,
    bar = 5,
    foobar = 8
};

var result = new RouteValueDictionary(toBeConverted);
annemartijn
  • 1,538
  • 1
  • 23
  • 45
23

If the dynamic value in question was created via deserialization from Json.Net as you mentioned in your comments, then it should be a JObject. It turns out that JObject already implements IDictionary<string, JToken>, so you can use it as a dictionary without any conversion, as shown below:

string json = 
     @"{ ""blah"" : { ""2"" : ""foo"", ""5"" : ""bar"", ""8"" : ""foobar"" } }";

var dict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
dynamic dyn = dict["blah"];

Console.WriteLine(dyn.GetType().FullName);     // Newtonsoft.Json.Linq.JObject
Console.WriteLine(dyn["2"].ToString());        // foo

If you would rather have a Dictionary<string, string> instead, you can convert it like this:

Dictionary<string, string> newDict = 
          ((IEnumerable<KeyValuePair<string, JToken>>)dyn)
                     .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ToString());
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
14

You can use Json.Net to deserialize it to dictionary.

string json = dynamicObject.ToString(); // suppose `dynamicObject` is your input
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
Wasif Hossain
  • 3,900
  • 1
  • 18
  • 20
  • 4
    Okay but `string json = dynamicObject.ToString()` didn't work out. You need `string json = JsonConvert.SerializeObject(dynamicObject);` – derloopkat May 17 '18 at 15:12
4

Very similar to ema answer, but with a one-liner using LINQ magic:

Dictionary<string, object> myDict = sourceObject.GetType().GetProperties().ToDictionary(prop => prop.Name, prop => prop.GetValue(sourceObject, null));
Ada
  • 261
  • 1
  • 3
  • 14
3

Another way is using System.Web.Helpers.Json included in .NET 4.5.

Json.Encode(object) and Json.Decode. Like:

Json.Decode<Generic.Dictionary<string, string>>(value);

MSDN: https://msdn.microsoft.com/en-us/library/gg547931(v=vs.111).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

Regards, MarianoC.

MarianoC
  • 341
  • 3
  • 3
0

You can do it with jsonSerializer. And it requires System.Net.Extensions reference. Here is a sample code.

var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string,string>>(jsonText);
var place = dict["8"]; // "foobar"
Anıl Canlı
  • 432
  • 9
  • 20
0

If you use the dynamic implementation here:

https://github.com/b9chris/GracefulDynamicDictionary

You can get the Dictionary right from the implementation. One advantage to using the above implementation (written for an answer to another SO question), is you can shift easily between the specific implementation and dynamic, like so:

    dynamic headers = new DDict();
    headers.Authorization = token;
    if (doesNeedSiteId)
        headers.SiteId = siteId;
    
    await post(headers);
}

protected async Task post(DDict headers)
{
    var dict = headers.GetDictionary(); // Dictionary<string, object>

In the above, the headers collection is conveniently created as a dynamic, but, the underlying specific implementation is DDict, and the post() method accepts it even though you've declared it as dynamic and used its features.

Chris Moschini
  • 36,764
  • 19
  • 160
  • 190
0

One line solution to convert your JSON text to Dictionary:

IDictionary<string, object> dict = new JavaScriptSerializer().Deserialize<IDictionary<string, object>>(json);

Then

if (dict.ContainsKey("field1"))
   string field1value = dict["field1"];
Dmitry Shashurov
  • 1,148
  • 13
  • 11