gpt4 book ai didi

c# - 反序列化呈现为不同类型的节点

转载 作者:太空宇宙 更新时间:2023-11-03 22:40:02 24 4
gpt4 key购买 nike

我正在遍历一个 JSON 文件文件夹,并试图从中提取一些信息;但是,我发现这样做非常困难。

我已经开始构建要反序列化的对象。我有一个特定的节点,我通常会反序列化为一个对象,但当它为空时,它会显示为一个空数组。请参阅下面示例 JSON 中的 definition 字段:

{
"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;

错误:

An unhandled exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll

Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,JsonProcessReader.Models.Stages+IntegrationDefinition]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

最佳答案

空数组与字典结构不兼容,这会导致您看到的错误。由于您似乎无法轻易更改 JSON,因此您需要使用 JsonConverter来处理这种情况。这是一个应该适合您的通用方法:

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 片段暂时加载到 JToken 中,然后在尝试转换之前检查它是否真的是一个对象。因此,如果它是一个数组或其他无法正确转换的标记类型,它将返回一个空的 T 实例。

要使用转换器,只需将 [JsonConverter] 属性添加到您的字典属性中,如下所示:

public class Integration
{
...
[JsonConverter(typeof(TolerantObjectConverter<Dictionary<string, Definition>>))]
public Dictionary<string, Definition> definition { get; set; }
}

这是一个工作演示:https://dotnetfiddle.net/83dQoC

关于c# - 反序列化呈现为不同类型的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52738560/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com