startupsmith
startupsmith

Reputation: 5764

Parsing Complex JSON without reflected objects?

I am using an API that outputs JSON objects with many attributes including sub-objects. So far all of the examples that I have found for JSON in C# assume that the .Net object has been serialized to JSON and can be deserialized back into the .Net object.

I am trying to find a solution where I can read the JSON into some generic object that I can then manually assign values to my Business Object properties by selecting the values from the generic objects.

Possibly something like ADO.Nets Datables and DataRows where you can pass the column names to the DataRow objects and get the values of the columns. This may be a bit too advanced but basically I want to be able to read the JSON objects by iterating through them and select values from the objects by passing the attribute names. This means that I won't be deserializing all of the attributes into my business objects, I will just be taking specific attributes from the JSON objects and assigning their values to the properties of my business objects.

What is a good solution for doing this?

Here is an example of two objects output from the API:

{
  "appt": [
    {
      "d": 1331717080000, 
      "id": "112115", 
      "inv": [
        {
          "comp": [
            {
              "alarm": [
                {
                  "action": "DISPLAY", 
                  "desc": [
                    {}
                  ], 
                  "trigger": [
                    {
                      "rel": [
                        {
                          "m": 5, 
                          "neg": true, 
                          "related": "START"
                        }
                      ]
                    }
                  ]
                }
              ], 
              "apptId": "112115", 
              "calItemId": "112115", 
              "ciFolder": "112111", 
              "class": "PUB", 
              "compNum": 0, 
              "d": 1331717080000, 
              "desc": [
                {
                  "_content": ""
                }
              ], 
              "descHtml": [
                {
                  "_content": "<html><body></body></html>"
                }
              ], 
              "e": [
                {
                  "d": "20120314T130000", 
                  "tz": "Pacific/Auckland", 
                  "u": 1331683200000
                }
              ], 
              "fb": "B", 
              "fba": "B", 
              "isOrg": true, 
              "loc": "", 
              "method": "PUBLISH", 
              "name": "Test Appt", 
              "noBlob": true, 
              "or": {
                "a": "[email protected]", 
                "d": "Liam Smith", 
                "url": "[email protected]"
              }, 
              "rsvp": false, 
              "s": [
                {
                  "d": "20120314T090000", 
                  "tz": "Pacific/Auckland", 
                  "u": 1331668800000
                }
              ], 
              "seq": 0, 
              "status": "CONF", 
              "transp": "O", 
              "uid": "aa2e4fe4-c636-4660-ae92-3e7041fe5669", 
              "url": "", 
              "x_uid": "aa2e4fe4-c636-4660-ae92-3e7041fe5669"
            }
          ], 
          "compNum": 0, 
          "id": 112114, 
          "seq": 0, 
          "type": "appt", 
          "tz": [
            {
              "daylight": [
                {
                  "hour": 2, 
                  "min": 0, 
                  "mon": 9, 
                  "sec": 0, 
                  "week": -1, 
                  "wkday": 1
                }
              ], 
              "dayname": "NZDT", 
              "dayoff": 780, 
              "id": "Pacific/Auckland", 
              "standard": [
                {
                  "hour": 3, 
                  "min": 0, 
                  "mon": 4, 
                  "sec": 0, 
                  "week": 1, 
                  "wkday": 1
                }
              ], 
              "stdname": "NZST", 
              "stdoff": 720
            }
          ]
        }
      ], 
      "l": "112111", 
      "rev": 72672, 
      "s": 0, 
      "uid": "aa2e4fe4-c636-4660-ae92-3e7041fe5669"
    }, 
    {
      "d": 1331717176000, 
      "id": "112117", 
      "inv": [
        {
          "comp": [
            {
              "alarm": [
                {
                  "action": "DISPLAY", 
                  "desc": [
                    {}
                  ], 
                  "trigger": [
                    {
                      "rel": [
                        {
                          "m": 5, 
                          "neg": true, 
                          "related": "START"
                        }
                      ]
                    }
                  ]
                }
              ], 
              "apptId": "112117", 
              "calItemId": "112117", 
              "ciFolder": "112111", 
              "class": "PUB", 
              "compNum": 0, 
              "d": 1331717176000, 
              "desc": [
                {
                  "_content": ""
                }
              ], 
              "descHtml": [
                {
                  "_content": "<html><body></body></html>"
                }
              ], 
              "e": [
                {
                  "d": "20120315T120000", 
                  "tz": "Pacific/Auckland", 
                  "u": 1331766000000
                }
              ], 
              "fb": "B", 
              "fba": "B", 
              "isOrg": true, 
              "loc": "", 
              "method": "PUBLISH", 
              "name": "test 2", 
              "noBlob": true, 
              "or": {
                "a": "[email protected]", 
                "d": "Liam Smith", 
                "url": "[email protected]"
              }, 
              "rsvp": false, 
              "s": [
                {
                  "d": "20120315T100000", 
                  "tz": "Pacific/Auckland", 
                  "u": 1331758800000
                }
              ], 
              "seq": 0, 
              "status": "CONF", 
              "transp": "O", 
              "uid": "4081f711-9742-42bd-a5dc-8bc9ddc3305d", 
              "url": "", 
              "x_uid": "4081f711-9742-42bd-a5dc-8bc9ddc3305d"
            }
          ], 
          "compNum": 0, 
          "id": 112116, 
          "seq": 0, 
          "type": "appt", 
          "tz": [
            {
              "daylight": [
                {
                  "hour": 2, 
                  "min": 0, 
                  "mon": 9, 
                  "sec": 0, 
                  "week": -1, 
                  "wkday": 1
                }
              ], 
              "dayname": "NZDT", 
              "dayoff": 780, 
              "id": "Pacific/Auckland", 
              "standard": [
                {
                  "hour": 3, 
                  "min": 0, 
                  "mon": 4, 
                  "sec": 0, 
                  "week": 1, 
                  "wkday": 1
                }
              ], 
              "stdname": "NZST", 
              "stdoff": 720
            }
          ]
        }
      ], 
      "l": "112111", 
      "nextAlarm": 1331758500000, 
      "rev": 72674, 
      "s": 0, 
      "uid": "4081f711-9742-42bd-a5dc-8bc9ddc3305d"
    }
  ]
}

Upvotes: 1

Views: 2021

Answers (2)

L.B
L.B

Reputation: 116168

If your are using Json.Net you can make use of dynamic keyword. Here is a sample code using your json string.

dynamic obj = JsonConvert.DeserializeObject(jsonstr);
Console.WriteLine("{0} {1}", obj.appt[0].inv[0].comp[0].method, obj.appt[1].id);

or

foreach (var appt in obj.appt)
{
    Console.WriteLine("{0} {1}", appt.inv[0].comp[0].method, appt.id);
}

in case you are using a framerork < 4.0, an uglier usage is also possible

JObject obj = (JObject)JsonConvert.DeserializeObject(jsonstr);
foreach (var appt in obj["appt"])
{
    Console.WriteLine("{0} {1}", appt["inv"][0]["comp"][0]["method"], appt["id"]);
}

Upvotes: 4

Sergii Kudriavtsev
Sergii Kudriavtsev

Reputation: 10522

You can deserialize JSON into Dictionary<string, object> using standard JavaScriptSerializer class. All the child complex objects will also be automatically deserialize to nested Dictionary<string, object> objects, so if you need to access some variable from deeps of your JSON then you can just subsequently cast all parent objects to nested Dictionary<string, object> and traverse to necessary field.

Upvotes: 0

Related Questions