首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反序列化以不同类型表示的节点

反序列化以不同类型表示的节点
EN

Stack Overflow用户
提问于 2018-10-10 10:51:47
回答 1查看 193关注 0票数 1

我正在浏览一个JSON文件文件夹,并试图从它们中提取一些信息;然而,我发现很难做到这一点。

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

代码语言:javascript
复制
{
  "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),我认为最好使用字典,但是当出现空数组时会引发错误。

代码语言:javascript
复制
 [JsonProperty("definition")]
 public Dictionary<string, Definition> definition;

错误:

Newtonsoft.Json.JsonSerializationException类型的未处理异常发生在Newtonsoft.Json.dll中 附加信息:无法将当前JSON数组(例如,1,2,3)反序列化为'System.Collections.Generic.Dictionary`2System.String,JsonProcessReader.Models.Stages+IntegrationDefinition‘类型,因为该类型需要一个JSON对象(例如{“名称”:“值”})才能正确反序列化。 要修复此错误,要么将JSON更改为JSON对象(例如,{"name":"value"}),要么将反序列化类型更改为数组,或者将实现集合接口(例如ICollection、IList)的类型改为可以从JSON数组反序列化的列表。还可以将JsonArrayAttribute添加到该类型中,以强制它从JSON数组中反序列化。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-11 04:47:04

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

代码语言:javascript
复制
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]属性,如下所示:

代码语言:javascript
复制
public class Integration
{
    ...
    [JsonConverter(typeof(TolerantObjectConverter<Dictionary<string, Definition>>))]
    public Dictionary<string, Definition> definition { get; set; }
}

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52738560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档