2014-12-24 113 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類看起來像下面想不使用字符串文字?