如何使用Newtonsoft反序列化可以是数组或字典的对象?

我正在使用一个API来返回我需要反序列化的json对象。 我的问题是这些对象的一个​​成员有时是一个空数组(“[]”),有时是一个字典(“{”1“:{…},”2“:{…}}” )。 我想将它反序列化为数组或字典,因为我不关心ID,我只想要所有对象的列表。 这是我如何反序列化对象:

var response = JsonConvert.DeserializeObject(json); 

这是Response类的定义:

 public class Response { [JsonProperty(PropertyName = "variations")] public Dictionary Variations { get; set; } } 

当Response在其变体字段中包含字典时它很有效,但是当它包含一个空数组时它会失败。 我从Newtonsoft得到一个错误,说数组不能被反序列化为字典。 如果我将Variations属性定义为数组,它适用于空数组,但是当它是字典时它会失败。 我可以做什么来正确地反序列化两个可能的值,或者忽略空数组并将Variations设置为null,当它是一个数组而不是失败时。

谢谢。

这是卡尔的例子中的一个变化(抱怨双关语)。 我有类似的需求,但我没有返回字典,而是需要一个数组。 我正在使用的API说它返回一个数组。 但是,在结果中只有一个项目的情况下,它将作为对象返回!

 public class VarationsContainer { [JsonIgnore] public Varation[] Varations { get { return ParseObjectToArray(VariationObject); } } [JsonProperty(PropertyName = "varations")] public object VarationsObject { get; set; } protected T[] ParseObjectToArray(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(json); } else { return new T[1] { JsonConvert.DeserializeObject(json) }; } } } 

我希望这对其他一些悲伤的API消费者有用。

这里是使用JsonConverter的替代解决方案

 public class Response { [JsonProperty(PropertyName = "variations")] [JsonConverter(typeof(EmptyArrayOrDictionaryConverter))] public Dictionary Variations { get; set; } } public class EmptyArrayOrDictionaryConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType.IsAssignableFrom(typeof(Dictionary)); } 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); } } 

这是我使用的解决方案:

  public Dictionary Variations { get { var json = this.VariationsJson.ToString(); if (json.RemoveWhiteSpace() == EmptyJsonArray) { return new Dictionary(); } else { return JsonConvert.DeserializeObject>(json); } } } [JsonProperty(PropertyName = "variations")] public object VariationsJson { get; set; } 

基本上,变体首先在基本对象中反序列化。 当我想读取值时,我检查对象是否为空数组,如果是,我返回一个空字典。 如果对象是一个好的字典,我将其反序列化并返回它。