В C#, как моделировать объект JSON с несколькими вложенными массивами?

Я получаю этот ответ JSON от системы, к которой я подключаюсь, и пытаюсь найти лучший способ десериализовать его в объект c#. В настоящее время я использую RestSharp который кажется довольно прямым для использования, но формат JSON немного озадачивает меня. Вот формат, который приходит в качестве:

[
  {"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"]
           ]
  }
] 

вот мой текущий код:

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;

но, как сказано выше, я пытаюсь выяснить, правильный способ модели TicketResults объект для поддержки десериализации этого сообщения выше.

В идеале я хотел бы что-то вроде этого:

 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;}
 }

и в этом примере выше, сделать три записи в коллекции билетов.

кроме того, является ли вышеуказанный формат JSON нормальным, поскольку я никогда не видел, чтобы это разбилось на отдельную схему и раздел данных (я вижу, где это может сэкономить место, но в этом случае сообщения не такие большие)

3 ответов


Я согласен, что формат json вполне ... бестолковый. Вот как моделировать ваш 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; }
    }

я смог заставить вашу строку (неизмененную) десериализоваться с JSON.Net Вот так:

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

Дайте мне знать, если у вас все еще есть проблемы.


в Visual Studio 2012 и выше, и вы можете перейти к Edit > Paste Special > Paste JSON as classes. Он создает следующий код, указанный в вашем примере, вставленном из буфера обмена.

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);

у вас есть какой-либо контроль над структурой возвращаемого JSON? Это дурацкий. По какой-то причине имена полей и данные разделяются. Если формат был немного более разумным, как:

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

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

тогда у вас будет шанс сериализовать его в свой класс билетов. Однако без переработки структуры JSON, что я не рекомендую вам делать, класс C#, который вы сериализуете, должен будет соответствовать структуре JSON.

небось может придумать промежуточный класс для хранения данных JSON, как это происходит с вами. Затем вы можете перебирать эти объекты и создавать из них экземпляры класса Ticket. По крайней мере, таким образом вы получите структуру данных, с которой можете работать.