2012-08-31 26 views
3

我正在使用一個API,它返回一個我需要反序列化的json對象。我的問題是,這些對象的成員之一有時是一個空數組(「[]」),有時是一個字典(「{」1「:{...},」2「:{...}}」 )。我想將它反序列化爲數組或字典,因爲我不關心這些ID,我只想要一個所有對象的列表。這裏是我反序列化對象:如何使用Newtonsoft反序列化可以是數組或字典的對象?

var response = JsonConvert.DeserializeObject<Response>(json); 

這裏是Response類的定義:

public class Response 
{ 
    [JsonProperty(PropertyName = "variations")] 
    public Dictionary<int, Variation> Variations { get; set; } 
} 

它運作良好,當響應包含在它的變化領域的字典,但它失敗時它包含一個空數組。我從Newtonsoft得到一個錯誤,說一個數組不能被反序列化成一個字典。如果我將Variations屬性定義爲數組,則它適用於空數組,但它在字典時失敗。我可以做什麼來正確反序列化兩個可能的值,或者忽略空數組,並將變量設置爲null,而不是失敗。

謝謝。

+1

那麼,什麼是一個混混來源:(我敢打賭,它是由PHP來了,是吧? – 2012-08-31 20:32:56

+0

我所看到的建議「文本轉換之前更換」,但我覺得一個替代解決方案它也可以通過一個自定義的JsonConverter來完成 – 2012-08-31 20:38:40

+0

@pst:這是一個好主意,沒有想到這麼做 – Carl

回答

0

這裏是我所使用的溶液:

public Dictionary<int, Variation> Variations 
    { 
     get 
     { 
      var json = this.VariationsJson.ToString(); 
      if (json.RemoveWhiteSpace() == EmptyJsonArray) 
      { 
       return new Dictionary<int, Variation>(); 
      } 
      else 
      { 
       return JsonConvert.DeserializeObject<Dictionary<int, Variation>>(json); 
      } 
     } 
    } 

    [JsonProperty(PropertyName = "variations")] 
    public object VariationsJson { get; set; } 

基本上,變化在鹼性對象首先被反序列化。當我想讀取值時,我檢查對象是否爲空數組,如果是這樣,我返回一個空字典。如果對象是一本好字典,我將其反序列化並返回。

2

以下是Carl的例子中的一個變體(對於雙關語)。我有類似的需求,但我不需要返回字典,而需要一個數組。我使用的API說它返回一個數組。但是,在結果中只有一個項目的情況下,它將作爲對象返回!

public class VarationsContainer 
{ 
    [JsonIgnore] 
    public Varation[] Varations 
    { 
     get 
     { 
      return ParseObjectToArray<Variation>(VariationObject); 
     } 
    } 

    [JsonProperty(PropertyName = "varations")] 
    public object VarationsObject { get; set; } 

    protected T[] ParseObjectToArray<T>(object ambiguousObject) 
    { 
     var json = ambiguousObject.ToString(); 
     if (String.IsNullOrWhiteSpace(json)) 
     { 
      return new T[0]; // Could return null here instead. 
     } 
     else if (json.TrimStart().StartsWith("[")) 
     { 
      return JsonConvert.DeserializeObject<T[]>(json); 
     } 
     else 
     { 
      return new T[1] { JsonConvert.DeserializeObject<T>(json) }; 
     } 
    } 
} 

我希望這對其他一些令人傷心的API消費者很有用。

+0

+1爲我省去了很多冤枉的感謝。適用於對象/數組(在我的情況下爲ToList())。 –

1

這裏使用JsonConverter

public class Response 
{ 
    [JsonProperty(PropertyName = "variations")] 
    [JsonConverter(typeof(EmptyArrayOrDictionaryConverter))] 
    public Dictionary<int, Variation> Variations { get; set; } 
} 


public class EmptyArrayOrDictionaryConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType.IsAssignableFrom(typeof(Dictionary<string, object>)); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     JToken token = JToken.Load(reader); 
     if (token.Type == JTokenType.Object) 
     { 
      return token.ToObject(objectType); 
     } 
     else if (token.Type == JTokenType.Array) 
     { 
      if (!token.HasValues) 
      { 
       // create empty dictionary 
       return Activator.CreateInstance(objectType); 
      } 
     } 

     throw new JsonSerializationException("Object or empty array expected"); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value); 
    } 
} 
相關問題