In C#, how do I model a JSON object with multiple nested arrays?

I am getting this JSON response from a system I am connecting to and trying to figure out the best way to deserialize it into a C# object. I am currently using RestSharp which seems pretty straight forward to use but the format of the JSON is baffling me a bit. Here is the format that its coming in as:

[
  {"name": "Tickets:",
   "schema": [
    {"dataType": "string", "colName": "First", "idx": 0}, 
    {"dataType": "string", "colName": "Second", "idx": 1}, 
    {"dataType": "string", "colName": "Name", "idx": 2}
   ], 
   "data": [
            ["bill", "test", "joe"],
            ["bill2", "test2", "joe2"],
            ["bill3", "test3", "joe3"]
           ]
  }
] 

Here is my current code:

var url = "http://myUrl:10111";
var client = new RestClient { BaseUrl = url };

var request = new RestRequest { Method = Method.GET, Resource = "/search?fmt=Json", RequestFormat = DataFormat.Json };
request.AddHeader("accept", "application/json");

var response = client.Execute(request);
var wptResponse = new JsonDeserializer().Deserialize<TicketResults>(response);
return wptResponse;

but as stated above I am trying to figure out the correct way to model the TicketResults object to support deserializing this message above.

Ideally I would like something like this:

 public class TicketResults
 {
     public List<Ticket> Tickets {get;set;}
 }

 public class Ticket
 {
     public string First {get;set;}
     public string Second {get;set;}
     public string Name {get;set;}
 }

and in this example above would get three entries in the Tickets collection.

Also, is the above JSON format normal as i have never seen this broken out into separate schema and data section (I can see where it might save some space but in this case the messages are not that big)

Answers


I agree the json format is quite ... goofy. Here's how to model your dto:

    public class JsonDto
    {
        public string name { get; set; }
        public Schema[] schema {get; set;}
        public string[][] data { get; set; }
    }
    public class Schema
    {
        public string dataType { get; set; }
        public string colName { get; set; }
        public int idx { get; set; }
    }

I was able to get your string (unaltered) to deserialize with JSON.Net like this:

var jsonDto = JsonConvert.DeserializeObject<JsonDto[]>(json);

Let me know if you're still having trouble.


In Visual Studio 2012 and up and you can go to Edit > Paste Special > Paste JSON as classes. It produces the following code given your example pasted from clipboard.

public class Rootobject
{
    public Class1[] Property1 { get; set; }
}

public class Class1
{
    public string name { get; set; }
    public Schema[] schema { get; set; }
    public string[][] data { get; set; }
}

public class Schema
{
    public string dataType { get; set; }
    public string colName { get; set; }
    public int idx { get; set; }
}

string json = File.ReadAllText("json.txt");
Rootobject root = new Rootobject();
root.Property1 = JsonConvert.DeserializeObject<Class1[]>(json);

Do you have any control over the structure of the JSON being returned? It's kind of wacky. For some reason the field names and the data is separated out. If the format was a little more sensible like:

[
    {
        "First": "bill",
        "Second": "test",
        "Name": "joe"
    },

    {
        "First": "bill2",
        "Second": "test2",
        "Name": "joe2"
    },
]

Then you would have a shot at serializing it to your Ticket class. However, without reworking the JSON structure, which I don't recommend you do, the C# class that you are serializing to will have to match the JSON structure.

I suppose you could come up with an intermediary class to hold the JSON data as it comes to you. Then you could loop over those objets and create instances of the Ticket class out of them. At least that way you end up with a data structure you can work with.


Need Your Help

Why is 1899-12-30 the zero date in Access / SQL Server instead of 12/31?

sql-server ms-access

More out of curiosity than any real problem; the question came up today and I know I've seen 1899-12-30 used as a "default" date and a zero date in Access and older SQL Server apps. Just wondered ...

UIDevice uniqueIdentifier deprecated - What to do now?

ios deprecated uidevice

It has just come to light that the UIDevice uniqueIdentifier property is deprecated in iOS 5 and unavailable in iOS 7 and above. No alternative method or property appears to be available or forthco...