0

When I get to the third loop, it blows up because it can't find the "Row" on the table. Why?

var converter = new ExpandoObjectConverter();
dynamic deserializeObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);

foreach (var model in deserializeObject.Model)
{
    foreach (var table in model.Table)
    {
        foreach (var row in table.Row)
        {
            Console.WriteLine(row.BookId + ": " + row.BookName);
        }
    }
}

JSON:

{
  "Model": [
    {
      "Field1": "Field1Value",
      "Field2": "Field2Value",
      "Field3": "Field3Value",
      "Table": {
        "Row": [
          {
            "BookId": "1",
            "BookName": "Computer Architecture",
            "Category": "Computers",
            "Price": "125.60"
          },
          {
            "BookId": "2",
            "BookName": "Asp.Net 4 Blue Book",
            "Category": "Programming",
            "Price": "56.00"
          },
          {
            "BookId": "3",
            "BookName": "Popular Science",
            "Category": "Science",
            "Price": "210.40"
          },
          {
            "BookId": "4",
            "BookName": "Mission Impossible",
            "Category": "Adventure",
            "Price": "210.40"
          }
        ]
      }
    },
    {
      "ClientFirstName": "Jane",
      "ClientLastName": "Doe",
      "Table": [
        {
          "Row": [
            {
              "BookId": "1",
              "BookName": "Computer Architecture",
              "Category": "Computers",
              "Price": "125.60"
            },
            {
              "BookId": "3",
              "BookName": "Popular Science",
              "Category": "Science",
              "Price": "210.40"
            },
            {
              "BookId": "4",
              "BookName": "Mission Impossible",
              "Category": "Adventure",
              "Price": "210.40"
            }
          ]
        },
        {
          "Row": [
            {
              "BookId": "1",
              "BookName": "Computer Architecture",
              "Category": "Computers",
              "Price": "125.60"
            },
            {
              "BookId": "4",
              "BookName": "Mission Impossible",
              "Category": "Adventure",
              "Price": "210.40"
            }
          ]
        }
      ]
    }
  ]
}
1
  • check your json in jsonlint.com Commented Apr 7, 2016 at 2:39

2 Answers 2

2

The problem isn't with the way you're deserializing the object. Your json is different between the two objects that contain a table.

The first object is a table that has an array of rows:

    "Table": {
    "Row": [
      {
        "BookId": "1",
        "BookName": "Computer Architecture",
        "Category": "Computers",
        "Price": "125.60"
      },
      {
        "BookId": "2",
        "BookName": "Asp.Net 4 Blue Book",
        "Category": "Programming",
        "Price": "56.00"
      },
      {
        "BookId": "3",
        "BookName": "Popular Science",
        "Category": "Science",
        "Price": "210.40"
      },
      {
        "BookId": "4",
        "BookName": "Mission Impossible",
        "Category": "Adventure",
        "Price": "210.40"
      }
    ]
  }
}

And your second client object has an array of an array. In addition you have a second array of rows in that client object outside of the table array.

       "Table": [
    {
      "Row": [
        {
          "BookId": "1",
          "BookName": "Computer Architecture",
          "Category": "Computers",
          "Price": "125.60"
        },
        {
          "BookId": "3",
          "BookName": "Popular Science",
          "Category": "Science",
          "Price": "210.40"
        },
        {
          "BookId": "4",
          "BookName": "Mission Impossible",
          "Category": "Adventure",
          "Price": "210.40"
        }
      ]
    },
    {
      "Row": [
        {
          "BookId": "1",
          "BookName": "Computer Architecture",
          "Category": "Computers",
          "Price": "125.60"
        },
        {
          "BookId": "4",
          "BookName": "Mission Impossible",
          "Category": "Adventure",
          "Price": "210.40"
        }
      ]
    }

I'd recommend either formatting your json differently or creating a different method to loop though the two types of tables you have in that json. One being an object and the other an array.

For example. I changed your dynamic to a Newtonsoft Jobject which is in Newtonsoft.Json.Linq; This will pick up on both tables, one being an object and the second being an array.

       var converter = new ExpandoObjectConverter();
        var deserializeObject = JsonConvert.DeserializeObject<JObject>(jsonString, converter);

        foreach(var v in deserializeObject["Model"])
        {
            if(v["Table"] != null && v["Table"].Type == JTokenType.Object)
            {
                foreach (var x in v["Table"]["Row"])
                {
                    Console.Write(x["BookId"] + " : " + x["BookName"] + Environment.NewLine);
                }
            }
            else if (v["Table"].Type == JTokenType.Array)
            {
                foreach(var subTable in v["Table"])
                {
                    foreach (var row in subTable["Row"])
                    {
                        Console.Write(row["BookId"] + " : " + row["BookName"] + Environment.NewLine);
                    }
                }

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

Comments

1

Table property in your JSON was formatted as array in one instance and as object in another. The former deserializes to List<object> while the latter deserializes to KeyValuePair<string, object>.

You can check whether Table in the current instance is of type KeyValuePair<string, object> and then proceed accordingly :

foreach (var model in deserializeObject.Model)
{
    foreach (var table in model.Table)
    {
        if(table is KeyValuePair<string, object>)
        {
            foreach (var row in table.Value)
            {
                Console.WriteLine(row.BookId + ": " + row.BookName);
            }
        }
        else
        {
            foreach (var row in table.Row)
            {
                Console.WriteLine(row.BookId + ": " + row.BookName);
            }
        }
    }
}

dotnetfiddle demo

Comments

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.