2014-12-24 115 views
1

我想反序列化json,它返回不同参数的不同数据。 主要是我得到:反序列化动态json类型

{"posts": [{ "id" : 1, "name":"post1" },{ "id" : 1, "name":"post1" }]} 

但有时返回的数据

{"posts": false} 

我想反序列化这是下面的类

public class GetReaderResponse 
{ 
    public IEnumerable<ReaderPost> posts {get; set;} 
} 

public class ReaderPost 
{ 
    public int id {get; set;} 
    public string name{get; set;} 
} 

我使用C#,json.net但无法正确执行此操作。

Newtonsoft.Json.JsonConvert.DeserializeObject<GetReaderResponse>(dataString); 

回答

2

你可以建立一个自定义转换器,但是一个简单的方法来处理,这将是编写检测与posts属性的错误的错误处理程序:

var settings = new JsonSerializerSettings(); 

settings.Error += (sender, args) => 
{ 
    if (string.Equals("posts", args.ErrorContext.Path, StringComparison.OrdinalIgnoreCase)) 
    { 
     var currentObject = args.CurrentObject as GetReaderResponse; 

     currentObject.posts = Enumerable.Empty<ReaderPost>(); 

     args.ErrorContext.Handled = true; 
    } 
}; 

GetReaderResponse resp = 
    JsonConvert.DeserializeObject<GetReaderResponse>(json, settings); 

这台postsEnumerable.Empty<ReaderPost>。这仍然有点不令人满意,因为如果发生任何错误,该属性将被设置。你可以建立一个完整的自定义转换器来做这个更完整的解决方案。

下面是会照顾这一个转换器:

public class PostsConverter : JsonConverter 
{ 
    public override object ReadJson(
     JsonReader reader, 
     Type objectType, 
     object existingValue, 
     JsonSerializer serializer) 
    { 
     JToken val = JValue.ReadFrom(reader); 
     object result = null; 

     if (val.Type == JTokenType.Array) 
     { 
      result = val.ToObject<IEnumerable<ReaderPost>>(); 
     } 
     else if (val.Type == JTokenType.Boolean) 
     { 

      result = Enumerable.Empty<ReaderPost>(); 
     } 

     return result; 
    } 

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

    public override bool CanConvert (Type type) 
    { 
     return typeof(IEnumerable<ReaderPost>).IsAssignableFrom(type); 
    } 

    public override bool CanRead 
    { 
     get { return true; } 
    } 
} 

用法:

var settings = new JsonSerializerSettings(); 

settings.Converters = new [] { new PostsConverter() }; 

GetReaderResponse resp = 
    JsonConvert.DeserializeObject<GetReaderResponse>(json, settings); 

例子:https://dotnetfiddle.net/i9CXwp

+0

谢谢!这似乎运作良好 – Shubhan

0

试试这个:

public class GetReaderResponse 
{ 
    public bool posts { get; set; } 
    public ReaderPost[] post { get; set; } 
} 
+0

抱歉,我纠正了JSON一个错字。我两次都得到'帖子'。你的回答没有帮助。 – Shubhan

1

通过使用内置的LINQ to JSON JSON.NETs,你可以尝试成才这样的:

JObject jObject = JObject.Parse(json); 
GetReaderResponse response = new GetReaderResponse(); 
if (jObject["posts"] is JArray) 
    response = jObject.ToObject<GetReaderResponse>(); 

// Do something with the response object. 

其中json变量是JSON字符串你需要反序列化。

0

阅读@ Ilija的评论后,我想我可能找到了答案。

public class GetReaderResponse 
{ 
    public dynamic posts {get; set;} 
    public IEnumerable<ReaderPost> Posts 
    { 
     get 
     { 
      if (posts is bool) 
       return new ReaderPost[0]; 

      return posts.ToObject<IEnumerable<ReaderPost>>();    
     } 
    } 
} 

这听起来罚款或者它看起来凌乱:我没有,所以我修改了我的GetReaderResponse类看起来像下面想不使用字符串文字?