web-dev-qa-db-ja.com

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

上記のこの例では、Ticketsコレクションに3つのエントリがあります。

また、上記のJSON形式は正常です。これは、個別のスキーマとデータセクションに分割されているのを見たことがないためです(スペースを節約できる場所はわかりますが、この場合、メッセージはそれほど大きくありません)

8
leora

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

それでも問題が解決しない場合はお知らせください。

4
Fred

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

返されるJSONの構造を制御できますか?ちょっと風変わりです。何らかの理由で、フィールド名とデータが分離されています。形式が次のようにもう少し賢明だった場合:

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

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

次に、それをチケットクラスにシリアル化する方法を試してみます。ただし、JSON構造を作り直すことはお勧めしませんが、そうしないと、シリアル化するC#クラスがJSON構造と一致する必要があります。

JSONデータを保持するための中間クラスを考え出すことができると思います。次に、それらのオブジェクトをループして、それらからTicketクラスのインスタンスを作成できます。少なくともそうすれば、作業できるデータ構造になります。

1
d512