2017-08-01 4 views
2

をdesirializeに失敗しました。だから私はそれを返し、サーバーへのREST APIで返されるJSONデータをデシリアライズするためのデータ構造をJson.netをされて使用しています:は、異種JSONデータ

{ "keyXXX" : [[1,2,3,...]...], "last": 12345 } 

問題は、「キー」であります私はクラス/構造体を使用することはできませんので、最初の部分にIDictionary<string, int[][]>を使用しなければなりませんでしたが、 "最後"の部分は例外をスローします。配列の配列ではなく単一の整数。 これは私が試したものです:

var dec = JsonConvert.DeserializeObject<IDictionary<string, int[][]>>(data); 

これは、JSONの例外がスローされます。

Newtonsoft.Json.JsonSerializationException:エラーが 'System.Decimalの[] []' 型に値1501555920を変換します。パス '最後'。

//define a class 
public class DPInfo 
{ 
    public decimal[][] points { get; set; } 
    public long last { get; set; } 
} 
var dec = JsonConvert.DeserializeObject<DPInfo>(data); 

配列のフィールド名が動的であるため、これは動作しませんので、points意志が、この後に何も含まれていません。

これを修正することはできますか?

+0

JSONには1つの 'keyXXX'がありますか、それとも複数の'XXX'の値は? –

+0

ちょうど1つですが、その名前は変わります – fluter

答えて

1

あなたはこれを解決するために、カスタムJsonConverterが必要になります。ここでは動作するはずです:

public class DPInfoConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(DPInfo); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JObject obj = JObject.Load(reader); 
     JProperty points = obj.Properties().FirstOrDefault(p => p.Name != "last"); 

     DPInfo info = new DPInfo 
     { 
      key = points.Name, // remove this line if you don't need the key 
      points = points.Value.ToObject<decimal[][]>(), 
      last = (long)obj["last"] 
     }; 

     return info; 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

ちょうどあなたのクラスに[JsonConverter]属性追加し、それを使用するには:いつものようにデシリアライズ、その後

[JsonConverter(typeof(DPInfoConverter))] 
public class DPInfo 
{ 
    public string key { get; set; } // remove this line if you don't need the key 
    public decimal[][] points { get; set; } 
    public long last { get; set; } 
} 

を、それが動作するはずです:

string json = @" 
{ 
    ""keyXXX"": [[1, 2, 3]], 
    ""last"": 12345 
}"; 

DPInfo info = JsonConvert.DeserializeObject<DPInfo>(json); 

フィドル:https://dotnetfiddle.net/7S6STp

+0

これは完璧に動作します、ありがとう! – fluter

+0

問題ありません。お役に立てて嬉しいです。 –

1

JObject.Parseを使用して、文字列をdynamic変数に解析することができます。少なくとも文字列からJSONへの変換が成功することを保証しますが、それにアクセスする前に各プロパティに値があることを検証するのはあなた次第です。

あなたのケースでは文は次のようになります。

dynamic data = JObject.Parse("{ 'keyXXX' : [[1,2,3,...]...], 'last': 12345 }"); 
関連する問題