在反序列化时如何忽略JSON对象数组中的空白数组?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在反序列化时如何忽略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<JsonAppID> 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; }
}
但是当我尝试时,我得到以下异常:
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将抛出异常。在您的情况下,您的JsonAppID
类型对应于JSON对象 - 一组无序的名称/值对,以{
(左大括号)开头,以}
(右大括号)结束。遇到数组时,会抛出您看到的异常。
如果您希望以静默方式跳过对象数组中的无效值类型,可以为custom JsonConverter
引入ICollection<T>
,它就是这样:
public class TolerantObjectCollectionConverter<TItem> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return !objectType.IsArray && objectType != typeof(string) && typeof(ICollection<TItem>).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<TItem> ?? (ICollection<TItem>)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<TItem>(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<JsonAppID>))]
public List<JsonAppID> AppIds { get; set; }
[JsonProperty("unique_field_count")]
public int UniqueFieldCount { get; set; }
}
样本工作.Net fiddle。
以上是关于在反序列化时如何忽略JSON对象数组中的空白数组?的主要内容,如果未能解决你的问题,请参考以下文章