【问题标题】:Deserializing only root/specific json objects c#仅反序列化根/特定的json对象c#
【发布时间】:2018-07-01 09:17:19
【问题描述】:

所以我有一个简单的问题。我有一个非常大的 json 文件,它在一个数组中包含大约 20,000 个 json 对象,每个对象中都有 3 个额外的嵌套对象(彼此分开)。 示例:

    [
  {
    "id": 0,
    "name": "Dwarf remains",
    "exchangeable": false,
    "members": true,
    "placeholder_id": 17851,
    "actions": {
      "inventory": {
        "fourthop": "Destroy"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 1,
    "name": "Toolkit",
    "exchangeable": false,
    "members": true,
    "placeholder_id": 17852,
    "actions": {
      "inventory": {
        "fourthop": "Destroy"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 2,
    "name": "Cannonball",
    "exchangeable": true,
    "members": true,
    "placeholder_id": 17853,
    "values": {
      "value": 5,
      "alchemy_high": 3,
      "alchemy_low": 2
    },
    "actions": {
      "inventory": {
        "fourthop": "Drop"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 3,
    "name": "Nulodion\u0027s notes",
    "exchangeable": false,
    "members": true,
    "placeholder_id": 17854,
    "actions": {
      "inventory": {
        "0": "Read",
        "fourthop": "Destroy"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 4,
    "name": "Ammo mould",
    "exchangeable": false,
    "members": true,
    "placeholder_id": 17855,
    "values": {
      "value": 5,
      "alchemy_high": 3,
      "alchemy_low": 2
    },
    "actions": {
      "inventory": {
        "fourthop": "Drop"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 5,
    "name": "Instruction manual",
    "exchangeable": false,
    "members": true,
    "placeholder_id": 17856,
    "values": {
      "value": 10,
      "alchemy_high": 6,
      "alchemy_low": 4
    },
    "actions": {
      "inventory": {
        "0": "Read",
        "fourthop": "Drop"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 6,
    "name": "Cannon base",
    "exchangeable": true,
    "members": true,
    "noted_id": 7,
    "placeholder_id": 17857,
    "values": {
      "value": 187500,
      "alchemy_high": 112500,
      "alchemy_low": 75000
    },
    "actions": {
      "inventory": {
        "0": "Set-up",
        "fourthop": "Drop"
      },
      "world": {
        "secondop": "Take"
      }
    }
  },

  {
    "id": 8,
    "name": "Cannon stand",
    "exchangeable": true,
    "members": true,
    "noted_id": 9,
    "placeholder_id": 17858,
    "values": {
      "value": 187500,
      "alchemy_high": 112500,
      "alchemy_low": 75000
    },
    "actions": {
      "inventory": {
        "fourthop": "Drop"
      },
      "world": {
        "secondop": "Take"
      }
    }
  }
]

现在如果我只想反序列化每个项目的根对象:

"id": 8,
"name": "Cannon stand",
"exchangeable": true,
"members": true,
"noted_id": 9,
"placeholder_id": 17858,

(本节) 我是否仍然需要为嵌套在每个项目中的值、动作和世界对象创建其他三个附加类,或者是否有一种方法可以简单地使用一个仅类似于根对象的类而没有这三个区域并且仍然让它全部反序列化正常吗?

或者甚至只是简单地提取项目名称和 id# 并将它们放在一个列表中?我问是因为如果不可能的话,我宁愿不继续浪费我的时间。我已经阅读了其他几个线程,但似乎无法找到这个特定实例的明确指示。 我读过的关于反序列化嵌套 json 对象的其他线程和文章/教程倾向于谈论不是数组的 json 字符串,它们只希望抓取单个元素,或者嵌套的方式不同。

那么这可能吗?如果是这样,您能否简单地给我一个小提示或链接到可以解释这种想法的东西。不一定要非常深入,只是真的需要有人指出方向,这样我才能更容易找到它。我已经搜索了几个小时的主题,但没有运气。

还有一个额外的问题,存储项目名称和 ID 号(数据库除外)的最佳方式是什么,以便用户可以在具有自动完成功能的文本框/组合框中搜索项目名称,并且一旦项目是选择它将使用相应的 id 号在另一个 api 中搜索该号码。

是否有任何体面的方法可以做到这一点,或者我应该坚持我最初的想法,即简单地将这个 json 数组导入数据集,然后将其保存为 xml,然后在启动时简单地将 xml 导入数据集?

我宁愿避免这种情况,这样用户就不必经常检查 xml 文件的新版本,他们只需在每次启动时获取最新的 json 并加以利用。这样我只需要担心更改 api 上的文件。

注意:我试图确保这不是重复的帖子,并查看了几个线程但无济于事。但是,我只睡了几个小时,我完全有可能犯了错误。 如果我这样做了,并且这是重复的帖子,请告诉我,如果是,我提前道歉。我目前已尽最大努力确保我没有重复线程。

【问题讨论】:

  • 只需从目标类中省略您不想要的数据的属性
  • 哦,哇,我不认为这实际上会起作用,因为它看起来很简单。这将允许它在跳过那些嵌套元素后继续到下一个项目?此外,如果我创建了一个只获取项目 ID 和项目名称的类,然后创建一个存储该类列表的第二个类。应该可以正常工作吗?
  • 你没有显示任何代码,所以我不知道你是怎么做的,但结果将是一个包含这些东西的对象。
  • 好吧,那我误解了你所说的“省略”是什么意思。好吧,所以我仍然需要完整的结构。我猜想将其放入这些对象的列表中,然后仅将需要的数据复制到另一个列表中,然后处理原始数据可能是我采用的最佳途径。
  • 不,您可以为您想要的数据定义道具。如果您不想要操作集合,请不要包含它。结果已经是一个包含 a) 集合的 ) 对象,因此您无需担心该部分

标签: c# json object serialization nested


【解决方案1】:

您可以忽略不想反序列化的属性,也可以从目标类中删除该属性。

public class Inventory
{
    public string fourthop { get; set; }
}

public class World
{
    public string secondop { get; set; }
}

public class Actions
{
    public Inventory inventory { get; set; }
    public World world { get; set; }
}

public class RootObject
{
    public int id { get; set; }
    public string name { get; set; }
    public bool exchangeable { get; set; }
    public bool members { get; set; }
    public int placeholder_id { get; set; }
    [JsonIgnore]//Ignore deserialization
    public Actions actions { get; set; }
}

var result = JsonConvert.DeserializeObject<List<RootObject>>(json);

【讨论】:

  • 啊,我从来没有听说过。谢谢一百万,你真的为我节省了很多额外的时间来弄清楚我应该如何去做。所以我的原始代码基本上已经是正确的,我只需要进行一些小的更改,我就会设置它。非常感谢
  • 您不需要更改代码中的任何内容,除非您想更改设计。 [JsonIgnore] 用于告诉序列化程序永远不要序列化这些特定属性,主要是因为它不能或不应该被序列化。如果您只是不为某些属性提供值,那么它们无论如何都不会包含在序列化中,并且不需要更改代码。
  • 这就是我更改代码的意思。只需将这些属性添加到属性中。哈哈
  • @Matthew Arnold,不客气。如果有效,请将答案标记为已接受。
【解决方案2】:

“有没有一种方法可以简单地使用类似于根对象的类而没有这 3 个区域,并且仍然可以正确反序列化它?”

是的,你可以直接反序列化你想要的值,直接到一个列表:这是一个例子:

void Main()
{
    var json = File.ReadAllText(@"c:\temp\json.txt"); // your json
    var output = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Target>>(json);
}

public class Target
{
    [Newtonsoft.Json.JsonProperty("id")]
    public int Id { get; set; }

    [Newtonsoft.Json.JsonProperty("name")]
    public string Name { get; set; }

    [Newtonsoft.Json.JsonProperty("exchangeable")]
    public bool Exchangeable { get; set; }

    [Newtonsoft.Json.JsonProperty("members")]
    public bool Members { get; set; }

    [Newtonsoft.Json.JsonProperty("placeholder_id")]
    public int PlaceholderId { get; set; }

    [Newtonsoft.Json.JsonProperty("noted_id")]
    public int? NotedId { get; set; }
}

还有输出:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多