6

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

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, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral , PublicKeyToken=b77a5c561934e089]]' 不支持数组的反序列化。

从我所做的研究来看,这似乎应该很简单——任何人都知道我应该使用哪种 JSON 格式以及出了什么问题?如果我只做一个对象而不是一组对象,那么 JSON 反序列化就好了。

4

3 回答 3

4

是的,如果你有任何复杂的类型和日期,反序列化器不会反序列化字典对象。解决方案是使用 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();
于 2012-09-13T04:07:28.767 回答
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();

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

于 2012-09-13T00:36:44.643 回答
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>
            }
        }
于 2016-04-27T14:24:52.533 回答