我在我的项目中使用
Newtonsoft.Json
。我有这样的JObject
:
{
"4781":"Name 1",
"1577":"Name 2",
"9973":"Name 3"
}
我用
JObject.Parse()
成功解析了它。我需要从此 JObject 获取第一个密钥(“4781”)。我怎样才能得到它?
JObject
属性的整数索引访问。
如果您这样做
JObject.Parse(jsonString)[0]
,您会收到包含消息的 ArgumentException
使用无效键值访问 JObject 值:0。需要对象属性名称。”
演示 #1 此处。
我怀疑 Json.NET 是这样实现的,因为 JSON 标准指出,“一个对象是一组无序的名称/值对。”
话虽这么说,
JObject
继承自JContainer
,显式地实现了IList<JToken>
。 因此,如果您将 JObject
向上转换为 IList<JToken>
,您可以通过与文档顺序相对应的整数索引来访问属性:
IList<JToken> obj = JObject.Parse(jsonString);
var firstName = ((JProperty)obj[0]).Name;
演示小提琴 #2 这里。
或者,您可以使用 LINQ 来实现类型安全的解决方案,而无需任何转换:
using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var obj = JObject.Parse(jsonString);
var firstName = obj.Properties().Select(p => p.Name).FirstOrDefault();
演示小提琴 #3 这里。
我设法让 Newtonsoft.Json 为我工作的方法是为输出创建自定义类型。
注意:以下内容是在 PowerShell 7.4.6 中,其中支持泛型方法
示例:
enum MySampleEnum {
Public
Private
Unknown
}
class MySampleInfo {
[version]$Version
[datetime]$Date
[MySampleEnum]$Type
}
class MySampleObject {
[string]$Name
[int]$Count
[bool]$IsDone
[MySampleInfo]$Info
}
$JsonSample = [pscustomobject]@{
Name = 'aaa'
Count = 10
IsDone = $true
Info = [pscustomobject] @{
Version = '1.1.0'
Date = (Get-Date).AddDays(-1).AddHours(-1)
Type = [MySampleEnum]::Public
}
},
[pscustomobject]@{
Name = 'bbb'
Count = 20
IsDone = $false
Info = [pscustomobject] @{
Version = '1.2.0'
Date = (Get-Date).AddDays(-2).AddHours(-2)
Type = [MySampleEnum]::Private
}
} | ConvertTo-Json -Depth 2
# Deserialize the Json string into an Object
$obj = [Newtonsoft.Json.JsonConvert]::DeserializeObject[MySampleObject[]]($JsonSample)
# and then check out the object
$obj
# returns:
# Name Count IsDone Info
# ---- ----- ------ ----
# aaa 10 True MySampleInfo
# bbb 20 False MySampleInfo
$obj[0].Info
# returns:
# Version Date Type
# ------- ---- ----
# 1.1.0 09/11/2024 12:06:21 Public
$obj[0].Info.Version
$obj | gm
$obj.Info | gm
# Serialize the Object back into a Json string
$IndentedFormat = [Newtonsoft.Json.Formatting]::Indented
[Newtonsoft.Json.JsonConvert]::SerializeObject($obj,$IndentedFormat)