0

I need to deserialize the next Json string that has several nested Json arrays:

{"d1":[["11791452",[["980",""]]],["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["11791454",[["1070",""]]]]}

I try to do it in several steps, so far I'm able to deserialize three levels of nested arrays. As follow:

{"aOaOa":[[["1060",""],["1140",""],["1220",""],["1300",""]]]}

public class ThreeSimpleNestedArrays
{
    public List<List<string[]>> aOaOa;  //array of arrays of arrays

    public ThreeSimpleNestedArrays()
    {
        aOaOa = new List<List<string[]>>();
    }
}

But the problem arise when I add the extra string in the array structure:

{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}

public class ComplexNestedArray
{
    public List<Dictionary<string,List<string[]> >> TEST;

    public ComplexNestedArray()
    {
        TEST = new List<Dictionary<string, List<string[]>>>();
    }
}

I'm getting the next error message: "Unable to cast object of type 'System.String' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'."

What am I missing?

Can anybody suggest a way to deserialize an object like this nested within Json arrays using DataContractJsonSerializer?

The code I use to deserialize is the next:

//Works
 DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ThreeSimpleNestedArrays));
        ThreeSimpleNestedArrays root = (ThreeSimpleNestedArrays)dcJsonSer.ReadObject(str);
//Don't work
        DataContractJsonSerializer dcJsonSer = new DataContractJsonSerializer(typeof(ComplexNestedArray));
        ComplexNestedArray root = (ComplexNestedArray)dcJsonSer.ReadObject(str);

Btw, I'm able to deserilize the object when it is serilized as a Json Object as follow:

 {"TEST": [{"s": "11791453","aOa": [["1060",""],["1140",""],["1220",""],["1300",""]]},{"s": "123456","aOa":[["0","1"],["2","3"]]}]}    

using a class with two members (a string "s" and a List of string[] "aOa"), but without the names, when the object is serialized as an array, I'm unable to do it.

Any suggestion?

2
  • I think there is no simple way to achive that. The problem with your structure is that you have at the second level a struncture like this: string, string[]. So you have there mixed data types in a single array. Commented May 5, 2013 at 9:07
  • @rekire, yes, that would be my second task, but first I would like to understand if it is possible to read 3 nested arrays and/or what am I doing wrong, =/ Commented May 5, 2013 at 16:31

2 Answers 2

3

Ok, it looks like the DataContractJsonSerializer is smarter than I though .

It turns out that the way to deserialize that kid of nested objects array is with a class like this:

public class ComplexNestedArray
{
    //{"TEST": [["11791453",[["1060",""],["1140",""],["1220",""],["1300",""]]],["123456",[["0","1"],["2","3"]]]]}

    public List<List<object>> TEST { get; set; }
} 

After that, it is only a mater to do a couple of for cycles and casts to the appropriate class structure.

Btw, This is a MUST in your toolbox in case you have to deal with Json:

json2csharp

Sign up to request clarification or add additional context in comments.

Comments

0

Here is my solution. However I'll try to add later a way for your full json:

class Program {
    static void Main(string[] args) {
        new Program();
    }

    public Program() {
        string full = "{\"d1\":[[\"11791452\",[[\"980\",\"\"]]],[\"11791453\",[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]],[\"11791454\",[[\"1070\",\"\"]]]]}";
        string simple1 = "{\"aOa\":[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]}";
        string simple2 = "{\"aOaOa\":[[[\"1060\",\"\"],[\"1140\",\"\"],[\"1220\",\"\"],[\"1300\",\"\"]]]}";

        DataContractJsonSerializer d1 = new DataContractJsonSerializer(typeof(S1));
        S1 r1 = (S1)d1.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple1)));
        DataContractJsonSerializer d2 = new DataContractJsonSerializer(typeof(S2));
        S2 r2 = (S2)d2.ReadObject(new MemoryStream(Encoding.Default.GetBytes(simple2)));
        Console.WriteLine("done");
        Console.ReadKey();
    }

    [DataContract]
    class S1 {
        [DataMember]
        List<List<String>> aOa;
    }

    [DataContract]
    class S2 {
        [DataMember]
        List<List<List<string>>> aOaOa;
    }
}

4 Comments

Thanks!, I found a similar answer, but using a list of a string array List<List<string[]>> for the third nested array, though I'm still dealing when I add the string. I update my question, btw.
I try to use a member public List<List<Dictionary<string, List<string[]>>>> TEST; but this gives me the next error: "Unable to cast object of type 'System.String' to type 'System.Collections.ICollection'."
@Alx I tried some hours to get this running. IMHO it is impossible with normal deserialisation maybe it is possible with the interface IDataContractSurrogate, but I don't have the time to implement that.
I'll look at the hint, thanks for your support, I let you know if I found a way. =)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.