c# - 反序列化呈现为不同类型的节点
问题描述
我正在遍历一个 JSON 文件的文件夹,并试图从中提取一些信息;但是,我发现这样做非常困难。
我已经开始构建要反序列化的对象。我有一个特定的节点,我通常会反序列化为一个对象,但是当它为空时,它会显示为一个空数组。请参阅definition
下面示例 JSON 中的字段:
{
"name": "Example",
"description": "Example JSON",
"properties": {
"foo": "bar",
"foo1": "bar2",
"foo3": "bar4"
},
"stages": {
"This is a stage": {
"stageInfo1": "blah",
"stageInfo2": "blah",
"integration": {
"x": "x",
"y": "y",
"z": "z",
"definition": []
}
},
"Another Stage": {
"stageInfo1": "blah",
"stageInfo2": "blah",
"integration": {
"x": "x",
"y": "y",
"z": "z",
"definition": {
"5a4d7de4c6518": {
"Editable": true,
"ID": "5a4d7de4c6518",
"Name": "My example"
}
}
}
}
}
}
由于定义名称可以更改(在本例中为5a4d7de4c6518
),我认为最好使用字典,但是当出现空数组时会引发错误。
[JsonProperty("definition")]
public Dictionary<string, Definition> definition;
错误:
Newtonsoft.Json.dll 中出现“Newtonsoft.Json.JsonSerializationException”类型的未处理异常
附加信息:无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“System.Collections.Generic.Dictionary`2[System.String,JsonProcessReader.Models.Stages+IntegrationDefinition]”,因为该类型需要正确反序列化的 JSON 对象(例如 {"name":"value"})。
要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如可以从 JSON 数组反序列化。JsonArrayAttribute 也可以添加到类型中以强制它从 JSON 数组反序列化。
解决方案
空数组与字典结构不兼容,这会导致您看到的错误。由于您似乎无法轻松更改 JSON,因此您需要使用 aJsonConverter
来处理这种情况。这是一个适合您的通用方法:
class TolerantObjectConverter<T> : JsonConverter where T: new()
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
object result = new T();
if (token.Type == JTokenType.Object)
{
serializer.Populate(token.CreateReader(), result);
}
return result;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
这个转换器的工作原理是将相关的 JSON 片段临时加载到 a 中JToken
,然后在尝试转换之前检查它是否真的是一个对象。因此,如果它是一个数组或其他无法正确转换的令牌类型,它将返回一个空T
实例。
要使用转换器,只需[JsonConverter]
向您的字典属性添加一个属性,如下所示:
public class Integration
{
...
[JsonConverter(typeof(TolerantObjectConverter<Dictionary<string, Definition>>))]
public Dictionary<string, Definition> definition { get; set; }
}
这是一个工作演示:https ://dotnetfiddle.net/83dQoC
推荐阅读
- javascript - 以表格格式排列 JSON 字符串
- javascript - f.state 不是功能 wordpress
- android - Play 商店中有 0 台设备支持 Android 应用
- javascript - Javascript自定义回调函数
- typescript - Google pay:Ionic 2 应用程序中出现意外的开发人员错误
- css - 我无法让我的 svg:hover 工作
- python - 将 Python 项目转换为 C
- linux - 如何创建带有时间戳的动态日期?
- model-view-controller - 特殊字符问题
- python-3.6 - 如何将一个列表中的每个元素用作另一个列表的索引?