2017-08-01 89 views
2

所以我用Json.net反序列化由的REST API返回到服务器的JSON数据,它返回的数据结构为:未能desirialize异构JSON数据

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

的问题是“关键”的也是数据的一部分,它不是一个名为“key”的字段,所以我不能使用类/结构体,我必须使用IDictionary<string, int[][]>作为第一部分,但“最后”部分会抛出异常,因为它是一个整数而不是数组数组。 这是我已经试过:

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

这将引发异常的JSON:

Newtonsoft.Json.JsonSerializationException:错误转换值1501555920键入 'System.Decimal [] []'。路径'最后'。

//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中是否只有一个'keyXXX'或多个不同的'XXX'值? –

+0

只有一个,但它的名字各异 – 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 }");