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



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

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

{
"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),如可以从 JSON 数组反序列化的列表。还可以将 JsonArrayAttribute 添加到类型中,以强制它从 JSON 数组反序列化。
路径 '['json.appID'][2]',第 12 行,位置 6。

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

当预期的 JSON 值类型(对象、数组或原语)与观察到的类型不匹配时,Json.NET 将引发异常。 在您的情况下,您的JsonAppID类型对应于 JSON 对象 - 一组无序的名称/值对,以{(左大括号)开头,以}(右大括号)结尾。 当遇到数组时,将抛出您看到的异常。

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

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 小提琴。

相关内容

  • 没有找到相关文章

最新更新