43

I have this string:

[{ "processLevel" : "1" , "segments" : [{ "min" : "0", "max" : "600" }] }]

I'm deserializing the object:

object json = jsonSerializer.DeserializeObject(jsonString);

The object looks like:

object[0] = Key: "processLevel", Value: "1"
object[1] = Key: "segments", Value: ...

And trying to create a dictionary:

Dictionary<string, object> dic = json as Dictionary<string, object>;

but dic gets null.

What can be the issue ?

ohadinho
  • 6,894
  • 16
  • 71
  • 124
  • If "json as IDictionary", var json = JsonConvert.DeserializeObject(jsonString, new ExpandoObjectConverter()); // Maybe ExpandoObject is the dynamic object you were thinking. – TamusJRoyce Aug 18 '17 at 16:39

5 Answers5

43

See mridula's answer for why you are getting null. But if you want to directly convert the json string to dictionary you can try following code snippet.

    Dictionary<string, object> values = 
JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
RobPethi
  • 551
  • 9
  • 27
santosh singh
  • 27,666
  • 26
  • 83
  • 129
  • 5
    but I want to deserialize to a class that has properties as Dictionary and other normal properties. How can I do that? – Shilan Jun 24 '21 at 11:46
  • For my scenario I noticed that the property was read only. So the deserialization process couldn't set the value. In my case I changed to not be read only, and it worked!! But I think you can create a constructor that receive the property, if you prefer to keep it as read only – Henrique Nov 11 '21 at 12:33
10

I like this method:

using Newtonsoft.Json.Linq;
//jsonString is your JSON-formatted string
JObject jsonObj = JObject.Parse(jsonString);
Dictionary<string, string> dictObj = jsonObj.ToObject<Dictionary<string, object>>();

You can now access anything you want using the dictObj as a dictionary. You can also use Dictionary<string, string> if you prefer to get the values as strings.

Blairg23
  • 11,334
  • 6
  • 72
  • 72
7

The MSDN documentation for the as keyword states that the statement expression as type is equivalent to the statement expression is type ? (type)expression : (type)null. If you run json.GetType() it will return System.Object[] and not System.Collections.Generic.Dictionary.

In cases like these where the type of object into which I want to deserialize a json object is complex, I use an API like Json.NET. You can write your own deserializer as:

class DictionaryConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        Throw(new NotImplementedException());            
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Your code to deserialize the json into a dictionary object.

    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Throw(new NotImplementedException());   
    }
}

And then you can use this serializer to read the json into your dictionary object. Here's an example.

mridula
  • 3,203
  • 3
  • 32
  • 55
  • This answer on a related problem has the full source code for the solution: http://stackoverflow.com/a/31250524/356550 – smdrager May 11 '16 at 19:52
1

I had the same problem and found a solution to it

  • Very simple
  • No bugs
  • Tested on operational product

Step 1) Create a generic class with 2 property

     public class CustomDictionary<T1,T2> where T1:class where T2:class
      {
          public T1 Key { get; set; }
          public T2 Value { get; set; }
      }

Step 2) Create New class and inherit from first class

  public class SectionDictionary: CustomDictionary<FirstPageSectionModel, List<FirstPageContent>> 
    { 

    }

Step 3) Replace Dictionary and List

public Dictionary<FirstPageSectionModel, List<FirstPageContent>> Sections { get; set; }

and

 public List<SectionDictionary> Sections { get; set; }

Step 4) Serialize or Deserialize easely

 {
     firstPageFinal.Sections.Add(new SectionDictionary { Key= section,Value= contents });
     var str = JsonConvert.SerializeObject(firstPageFinal);
     var obj = JsonConvert.DeserializeObject<FirstPageByPlatformFinalV2>(str);
 }

Thanks a lot

-1

The problem is that the object is not of type Dictionary<string,object> or a compatible type, thus you can't cast directly. I would create a custom object and use Deserialize.

public class DeserializedObject{
    public string processLevel{get;set;}
    public object segments{get;set}
}

IEnumerable<DeserializedObject> object=jsonSerializer.Deserialize<IEnumerable<DeserializedObject>>(json);
Carles Company
  • 7,118
  • 5
  • 49
  • 75