反序列化包含Dictionary的对象列表

时间:2012-09-13 00:12:29

标签: c# .net json serialization

我已经看到很多例子似乎表明我正在做的事情应该有效,但无论出于何种原因,它都没有。我正在尝试反序列化一组对象,其中一个属性是Dictionary,如下所示:

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; }
}

第一个json字符串将整个事物封装在一个对象中 - 如果我运行它,它运行正常,但myObjects只是一个空列表。如果我运行第二个字符串(没有它被包装)我得到以下错误:

  

输入'System.Collections.Generic.Dictionary`2 [[System.String,   mscorlib,版本= 4.0.0.0,文化=中性,   PublicKeyToken = b77a5c561934e089],[System.String,mscorlib,   Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]'   不支持反序列化数组。

从我所做的研究看来,这应该是非常直接的 - 任何人都有任何关于我应该使用哪种JSON格式以及出了什么问题的想法?如果我只做一个对象而不是一个对象数组,JSON反序列化就好了。

3 个答案:

答案 0 :(得分:4)

是的,如果您有任何复杂的类型和日期,反序列化器不会特别反序列化该dictornary对象。解决方案是使用Newtonsoft.Json使用Jobject进行反序列化你可以把它作为一个例子并尝试..在你的情况下你可以把它带到var或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();

答案 1 :(得分:1)

Dictionary<string, string>看起来不像您期望的那样可序列化。我尝试了List<KeyValuePair<string, string>>,但这似乎也没有用。

我能想到的只有一些丑陋的东西会将你的JSON转换为自定义类型,然后将其转换为字典。因此,完全按原样使用您的第二个JSON示例,您可以执行以下操作:

// 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();

我确信有更好的方法,但至少应该有效。

答案 2 :(得分:1)

对于OP来说显然有点晚了但是我今天打了类似的东西,用下面的方法来解决它:

        //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>
            }
        }