在反序列化时如何忽略JSON对象数组中的空白数组?

我正在使用Json.NET反序列化JSON。 如何在反序列化期间忽略在对象数组内意外发生的空白数组

我在本网站http://json.parser.online.fr/上测试了来自第三方的以下JSON,确认其格式正确:

{ "total_events": 3551574, "json.appID": [ { "count": 3551024, "term": 1 }, { "count": 256, "term": 2 }, [] /* <----- I need to ignore this empty array */ ], "unique_field_count": 2 } 

我想将它反序列化为以下模型:

 public class RootObject { [JsonProperty("total_events")] public int TotalEvents { get; set; } [JsonProperty("json.appID")] public List AppIds { get; set; } [JsonProperty("unique_field_count")] public int UniqueFieldCount { get; set; } } public class JsonAppID { [JsonProperty(PropertyName = "count")] public int Count { get; set; } [JsonProperty(PropertyName = "term")] public string Term { get; set; } } 

但是当我尝试时,我得到以下exception:

Newtonsoft.Json.JsonSerializationException:无法将当前JSON数组(例如[1,2,3])反序列化为类型’JsonAppID’,因为该类型需要JSON对象(例如{“name”:“value”})才能正确反序列化。
要修复此错误,请将JSON更改为JSON对象(例如{“name”:“value”})或将反序列化类型更改为数组或实现集合接口的类型(例如ICollection,IList),例如List从JSON数组反序列化。 JsonArrayAttribute也可以添加到类型中以强制它从JSON数组反序列化。
路径'[‘json.appID’] [2]’,第12行,第6位。

如何忽略"json.appID"数组中不需要的空数组并成功反序列化我的模型?

当预期的JSON值类型(对象,数组或基元)与观察到的类型不匹配时,Json.NET将抛出exception。 在您的情况下,您的JsonAppID类型对应于JSON对象 – 一组无序的名称/值对,以{ (左括号)开头,以}结束(右大括号)。 遇到数组时,会抛出您看到的exception。

如果您希望以静默方式跳过对象数组中的无效值类型,可以为ICollection引入一个自定义JsonConverter ,它就是这样做的:

 public class TolerantObjectCollectionConverter : JsonConverter { public override bool CanConvert(Type objectType) { return !objectType.IsArray && objectType != typeof(string) && typeof(ICollection).IsAssignableFrom(objectType); } public override bool CanWrite { get { return false; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Get contract information var contract = serializer.ContractResolver.ResolveContract(objectType) as JsonArrayContract; if (contract == null || contract.IsMultidimensionalArray || objectType.IsArray) throw new JsonSerializationException(string.Format("Invalid array contract for {0}", objectType)); // Process the first token var tokenType = reader.SkipComments().TokenType; if (tokenType == JsonToken.Null) return null; if (tokenType != JsonToken.StartArray) throw new JsonSerializationException(string.Format("Expected {0}, encountered {1} at path {2}", JsonToken.StartArray, reader.TokenType, reader.Path)); // Allocate the collection var collection = existingValue as ICollection ?? (ICollection)contract.DefaultCreator(); // Process the collection items while (reader.Read()) { switch (reader.TokenType) { case JsonToken.EndArray: return collection; case JsonToken.StartObject: case JsonToken.Null: collection.Add(serializer.Deserialize(reader)); break; default: reader.Skip(); break; } } // Should not come here. throw new JsonSerializationException("Unclosed array at path: " + reader.Path); } } public static partial class JsonExtensions { public static JsonReader SkipComments(this JsonReader reader) { while (reader.TokenType == JsonToken.Comment && reader.Read()) ; return reader; } } 

然后将其应用于您的数据模型,如下所示:

 public class JsonAppID { [JsonProperty(PropertyName = "count")] public int Count { get; set; } [JsonProperty(PropertyName = "term")] public string Term { get; set; } } public class RootObject { [JsonProperty("total_events")] public int TotalEvents { get; set; } [JsonProperty("json.appID")] [JsonConverter(typeof(TolerantObjectCollectionConverter))] public List AppIds { get; set; } [JsonProperty("unique_field_count")] public int UniqueFieldCount { get; set; } } 

样本工作.Net小提琴 。