Reputation: 5797
I've seen a lot of examples that seem to indicate that what I'm doing should work, but for whatever reason, it doesn't. I'm trying to deserialize a collection of objects, one of the properties of which is a Dictionary, like so:
class Program
{
static void Main(string[] args)
{
var json = "{\"Collection\":[{\"ID\":\"1243\",\"Dictionary\":[{\"Key\":\"color\", \"Value\":\"red\"},{\"Key\":\"size\",\"Value\":\"large\"}]},{\"ID\":\"1243\",\"Dictionary\":[{\"Key\":\"color\", \"Value\":\"blue\"},{\"Key\":\"size\",\"Value\":\"small\"}]}]}";
//var json = "[{\"ID\":\"1243\",\"Dictionary\":[{\"Key\":\"color\", \"Value\":\"red\"},{\"Key\":\"size\",\"Value\":\"large\"}]},{\"ID\":\"1243\",\"Dictionary\":[{\"Key\":\"color\", \"Value\":\"blue\"},{\"Key\":\"size\",\"Value\":\"small\"}]}]";
List<MyObject> myObjects = new JavaScriptSerializer().Deserialize<List<MyObject>>(json);
}
}
[DataContract]
public class MyObject
{
[DataMember]
public string ID { get; set; }
[DataMember]
public Dictionary<string, string> Dictionary { get; set; }
}
The first json string encapsulates the whole thing in an object - if I run that one it runs fine but myObjects is just an empty list. If I run the second string (without it being wrapped) I get the following error:
Type 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' is not supported for deserialization of an array.
From the research I've done this seems like it should be pretty straight forward - anyone have any ideas as to which JSON format I should be using and what is going wrong? The JSON deserializes just fine if I just do one object instead of an array of objects.
Upvotes: 6
Views: 10191
Reputation: 13755
Obviously a little late to the part for the OP :) but I hit similar today and used the following to solve it:
//var json = "[{'firstName':'John', 'lastName':'Doe'},{'firstName':'Anna', 'lastName':'Smith'},{'firstName':'Peter','lastName': 'Jones'} ]";
//var json = "{ 'glossary': { 'title': 'example glossary','GlossDiv': { 'title': 'S','GlossList': { 'GlossEntry': { 'ID': 'SGML','SortAs': 'SGML','GlossTerm': 'Standard Generalized Markup Language','Acronym': 'SGML','Abbrev': 'ISO 8879:1986','GlossDef': { 'para': 'A meta-markup language, used to create markup languages such as DocBook.','GlossSeeAlso': ['GML', 'XML'] },'GlossSee': 'markup' } } } } }";
var json = "{ 'A': 'A0' , 'B' : { 'B2' : 'B2 - Val', 'B3' : [{'B30' : 'B30 - Val1' ,'B31' : 'B31 - Val1'}]}, 'C': ['C0', 'C1']}";
var jss = new JavaScriptSerializer();
try
{
// Deal with an Object root
var dict = jss.Deserialize<Dictionary<string, object>>(json);
//<do stuff>
}
catch (InvalidOperationException ioX)
{
// Deal with an Array Root
var dictionaries = jss.Deserialize<Dictionary<string, object>[]>(json);
foreach (var dict in dictionaries)
{
//<do stuff for each dictionary>
}
}
Upvotes: 1
Reputation: 100
Yeah true, the deserializers dont deserialize the dictornary object especailly if you have any complex types and dates. The solution for that is use Newtonsoft.Json use Jobject to deserialize you can take this as an example and try.. In your case you can take this to var or Jobject
JArray resources=(JArray)JsonConvert.DeserializeObject(objJson);
itemStores = resources.Select(resource => new Resource`enter code here`
{
SpaceUsed = long.Parse(resource["indexDiskMB"].ToString()),
ItemId =resource["id"].ToString(),
CountItems =Int32.Parse(resource["numItems"].ToString()),
ItemType=resource["type"].ToString()
}).ToList();
Upvotes: 4
Reputation: 40403
Looks like Dictionary<string, string>
is not serializable the way you'd expect. I tried List<KeyValuePair<string, string>>
instead, and that doesn't seem to work either.
Only thing I can think of is some ugly stuff that will convert your JSON into a custom type, and then convert it into a dictionary. So using your 2nd JSON example exactly as-is, you can do something like:
// Inside of MyObject class
[DataMember]
public Kvp<string, string>[] Dictionary { get; set; }
public Dictionary<string, string> GetDictionary()
{
return Dictionary.ToDictionary(x => x.Key, x => x.Value);
}
//////////////////
public class Kvp<T1, T2>
{
public T1 Key { get; set; }
public T2 Value { get; set; }
}
Dictionary<string, string> myDictionary = myObjects[0].GetDictionary();
I'm sure there's a much better way, but this should at least work.
Upvotes: 1