C# 反序列化时,如何忽略JSON对象数组中的空白数组?
我正在使用JSON.NET反序列化JSON。在反序列化过程中,如何忽略对象数组中意外出现的空白数组 我在本网站上测试了来自第三方的以下JSON,确认其格式正确:C# 反序列化时,如何忽略JSON对象数组中的空白数组?,c#,json,json.net,deserialization,C#,Json,Json.net,Deserialization,我正在使用JSON.NET反序列化JSON。在反序列化过程中,如何忽略对象数组中意外出现的空白数组 我在本网站上测试了来自第三方的以下JSON,确认其格式正确: { "total_events": 3551574, "json.appID": [ { "count": 3551024, "term": 1 }, { "count": 256, "term": 2 }, []
{
"total_events": 3551574,
"json.appID": [
{
"count": 3551024,
"term": 1
},
{
"count": 256,
"term": 2
},
[] /* <----- I need to ignore this empty array */
],
"unique_field_count": 2
}
{
“总事件”:3551574,
“json.appID”:[
{
“计数”:3551024,
“期限”:1
},
{
“计数”:256,
“期限”:2
},
[]/*Json.NET将在预期值类型(对象、数组或基元)与观察到的类型不匹配时引发异常。在您的情况下,JsonAppID
类型对应于一个Json对象-一组无序的名称/值对,以{
(左括号)开始,以}
结束(右大括号)。当遇到数组时,将引发您看到的异常
如果您希望以静默方式跳过对象数组中的无效值类型,则可以引入forICollection
,其功能如下:
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;
}
}
公共类TolerantObjectCollectionConverter:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
return!objectType.IsArray&&objectType!=typeof(string)&&typeof(ICollection).IsAssignableFrom(objectType);
}
公共重写bool可以写入{get{return false;}}
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
//获取合同信息
var contract=serializer.ContractResolver.ResolveContract(objectType)作为JsonArrayContract;
if(contract==null | | | contract.IsMultidimensionalArray | | | objectType.IsArray)
抛出新的JsonSerializationException(string.Format(“对{0}无效的数组约定”,objectType));
//处理第一个令牌
var tokenType=reader.SkipComments().tokenType;
if(tokenType==JsonToken.Null)
返回null;
if(tokenType!=JsonToken.StartArray)
抛出新的JsonSerializationException(string.Format(“预期为{0},在路径{2}处遇到{1}”)、JsonToken.StartArray、reader.TokenType、reader.path);
//分配集合
var collection=作为ICollection???(ICollection)合同存在的值。DefaultCreator();
//处理收集项目
while(reader.Read())
{
开关(reader.TokenType)
{
案例JsonToken.EndArray:
回收;
案例JsonToken.StartObject:
案例JsonToken.Null:
Add(序列化程序.反序列化(读取器));
打破
违约:
reader.Skip();
打破
}
}
//我不应该来这里。
抛出新的JsonSerializationException(“路径:“+reader.path”处的未关闭数组);
}
}
公共静态部分类JsonExtensions
{
公共静态JsonReader SkipComments(此JsonReader阅读器)
{
while(reader.TokenType==JsonToken.Comment&&reader.Read())
;
返回读取器;
}
}
然后将其应用于数据模型,如下所示:
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; }
}
公共类JsonAppID
{
[JsonProperty(PropertyName=“count”)]
公共整数计数{get;set;}
[JsonProperty(PropertyName=“term”)]
公共字符串项{get;set;}
}
公共类根对象
{
[JsonProperty(“总事件”)]
公共int TotalEvents{get;set;}
[JsonProperty(“json.appID”)]
[JsonConverter(类型(TolerantObjectCollectionConverter))]
公共列表appid{get;set;}
[JsonProperty(“唯一字段计数”)]
public int UniqueFieldCount{get;set;}
}
示例工作。听起来不像是有效的json
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; }
}