2016-06-15 6 views
5

Json.net(Newtonsoft.json)を使用して、下のjsonを処理するC#クラス(またはクラス)をどのように定義できますか?JSONからC#へ - jsonのサブフィールド名のないフィールドをリストしますか?

'data'フィールドは、レベル/説明サブフィールドのリストとして表示されますが、ではなく、の前にフィールド名が付いています。

「エラー」フィールドはエラー番号/エラーメッセージのサブフィールドのリストのようですが、ではなく、フィールド名の前にが付いています。

{ 
    "status": "error", 
    "data": [ 
    { 
     "warning" : "your input was wrong" 
    } 
    ], 
    "error": [ 
    { 
     "373": "Error description goes here" 
    } 
    ] 
} 

このクラス定義は解析エラーを生成しません。しかし、データとエラーの内容は正しくありません。

public class ApiResponse 
{ 
    [JsonProperty(PropertyName = "status")] 
    public string Status; 

    [JsonProperty(PropertyName = "data")] 
    public IEnumerable<KeyValuePair<string, string>> Data; 

    [JsonProperty(PropertyName = "error")] 
    public IEnumerable<KeyValuePair<int, string>> Errors; 
}; 

// this doesn't throw a parsing exception, but the resulting 
// Data and Errors fields are not correctly populated. 
var x = JsonConvert.DeserializeObject<ApiResponse>(SampleJson); 

ご協力いただきありがとうございます。

+0

これはあなたを助けるかもしれない:http://stackoverflow.com/questions/27744199/converting-array-to-ienumerablet –

答えて

4

DataErrorsのメンバーを、KeyValuePairsのIEnumerablesではなく、DictionariesのIEnumerablesとして定義してみてください。 (Json.Netは、あなたがそこに持っているものではありませんこれは、KeyValuePairsは、明示的なKeyValueプロパティを持つオブジェクトとしてJSONで表現することを期待しています。)

public class ApiResponse 
{ 
    [JsonProperty(PropertyName = "status")] 
    public string Status; 

    [JsonProperty(PropertyName = "data")] 
    public IEnumerable<Dictionary<string, string>> Data; 

    [JsonProperty(PropertyName = "error")] 
    public IEnumerable<Dictionary<int, string>> Errors; 
}; 

あなたはその後、SelectManyforeachループを使用してデータを読み出すことができます。

var x = JsonConvert.DeserializeObject<ApiResponse>(SampleJson); 
foreach (var kvp in x.Data.SelectMany(d => d)) 
{ 
    Console.WriteLine(kvp.Key + ": " + kvp.Value); 
} 
foreach (var kvp in x.Errors.SelectMany(d => d)) 
{ 
    Console.WriteLine(kvp.Key + ": " + kvp.Value); 
} 

フィドル:https://dotnetfiddle.net/KJuAPu

+0

Dictionary <>の使用に切り替えると、KeyValuePairよりもうまく機能します。辞書を使用して私の懸念は、複数の "警告"を持つことができるかのようにデータフィールドが表示されることです。私はエラー番号が1回だけ表示されると仮定して、エラーフィールドは適切であるように見えます。 – Tony

+0

この構造でも動作します。 'SelectMany'を使うと、各配列に辞書がいくつあるのか、各辞書にいくつの項目があるかに関わらず、すべてを得ることができます。フィドル:https://dotnetfiddle.net/mLZBec –

+0

私はそれを今見ます。私はそれが単なる辞書だと思っていました。それはIEnumerable >ではありません。基本的には、単一エントリ辞書のリストです。ありがとう。 – Tony

-1

作成したクラスにはいくつかの問題があります。 JSONの提供に従って、次のようなクラスを作成する必要があります。

public class Data 
    { 
     [JsonProperty(PropertyName = "warning")] 
     public string Warning { get; set; } 
    } 
    public class Error 
    { 
     [JsonProperty(PropertyName = "373")] 
     public string Col_373 { get; set; } 
    } 

    public class ApiResponse 
    { 
     [JsonProperty(PropertyName = "status")] 
     public string Status { get; set; } 
     [JsonProperty(PropertyName = "data")] 
     public List<Data> Data { get; set; } 
     [JsonProperty(PropertyName = "error")] 
     public List<Error> Error { get; set; } 
    } 

このような構造を設計したら、次のコードスニペットとしてオブジェクト構造に戻すことができます。それは、あなたがプロパティの名前と値と混同されているようです。

string json = "{\"status\":\"error\", \"data\": [{\"warning\" : \"your input was wrong\" }], \"error\": [{\"373\": \"Error description goes here\"}]}"; 

var res = JsonConvert.DeserializeObject<ApiResponse>(json); 

もう1つの観察。

"373"

を "エラーの説明がここに行く" キー/列名として番号を使用しないでください。

+0

OPがJSONをコントロールしているかどうかはわかりませんが、おそらくサードパーティのAPIです。その場合、エラーコードが '373'以外のものであったり、データが' warning'以外のものであれば、あなたのソリューションは動作しません。可変キー名を扱うことができるものが必要です。 –

+0

@BrianRogersあなたは正しいです、私はJSONを制御しません。 – Tony

+0

@トニー私の答えを見てください。 JSONで動作し、可変キー名を処理できます。 –

関連する問題