下面是一个PS函数,用来将PS对象转换为NS json.Net对象.

function ConvertTo-NSJson ( $psObject ) {
    $json = $psObject | ConvertTo-Json -Compress -Depth 10
    $nsJson = [Newtonsoft.Json.Linq.JObject]::Parse( $json )
    return $nsJson
}

这里下面是一个小的PS对象进行测试

$psObject = [PSCustomObject] @{
    number = 10
    text = 'My message'
    list = @( 'item1', 'item2', 'item3' )
    hash = @{ key1 = 'text value'; key2 = 2; key3 = $true }
}

如果我在命令提示符下运行函数的每一行,我会得到预期的json.Net对象.

PS > $json = $psObject | ConvertTo-Json -Compress -Depth 10
PS > $nsJson = [Newtonsoft.Json.Linq.JObject]::Parse( $json )
PS > $nsjson['text'].Value
My message
PS > $nsjson.Item('text').Value
My message
PS > $nsjson['number'].Value
10
PS > $nsjson.Item('number').Value
10
PS > $nsjson['list'][0].Value
item1
PS > $nsjson.Item('list')[0].Value
item1
PS > $nsjson['hash']['key1'].Value
text value
PS > $nsjson.Item('hash')['key1'].Value
text value
PS > 

原始属性的值是可用的,无论获取它们的方式如何.

如果现在我调用函数ConvertTo-NSJson.我也得到一个json.Net对象,但与之前的对象不同.

PS > $nsjson = ConvertTo-NSJson $psobject
PS > $nsjson['text'].Value          # return nothing
PS > $nsjson.Item('text').Value     # generate exception
GetValueInvocationException: Exception getting "Item": "Cannot convert argument "index", with value: "text", for "get_Item" to type "System.Int32": "Cannot convert value "text" to type "System.Int32". Error: "The input string 'text' was not in a correct format."""
PS > $nsjson.ToString()         # shows correct json content
{
  "number": 10,
  "text": "My message",
  "list": [
    "item1",
    "item2",
    "item3"
  ],
  "hash": {
    "key3": true,
    "key2": 2,
    "key1": "text value"
  }
}
PS > 

原始属性的值不可用. 第一种方法返回空值,第二种方法产生异常. 但是ToString输出显示nsjson对象包含所有属性和值.

我的错误在哪里? 为什么函数返回的json.Net对象没有相同的行为?

推荐答案

似乎必须将返回的$nsJson转换为JObject才能成功使用其方法:

[Newtonsoft.Json.Linq.JObject]$nsjson = ConvertTo-NSJson $psobject

$nsjson.Item('text').Value     # outputs My message

演示here.

我不完全确定为什么需要这样做,但正如在this answerMathias R. Jessen102中所解释的那样,PowerShell命令没有静态返回类型.现在JObject显式和通过继承以及IDynamicMetaObjectProvider实现了许多不同的索引器,PS解释器似乎对调用哪个索引器感到困惑.将类型指定为JObject似乎可以解决问题.

最后,请注意,JObject只能代表JSON object,这是pair of curly brackets surrounding zero or more name/value pairs.如果您的ConvertTo-NSJson函数可能需要解析JSON数组或原语,您应该解析到JToken:

function ConvertTo-NSJson ( $psObject ) {
    $json = $psObject | ConvertTo-Json -Compress -Depth 10
    $nsJson = [Newtonsoft.Json.Linq.JToken]::Parse( $json )
    return $nsJson
}

Json相关问答推荐

Bash和echo命令出现意外结果

集成wix.comstore API|变音符号问题

nlohmann json:为什么我会得到一个解析错误?

使用 jq 获取所有嵌套键和值

JOLT分裂和数组数据

转换为Json时忽略内部对象中的数组

jq: Select 何时来自另一个数组的值与此 json 中的值匹配

嵌套存储在字符串变量中的 JSON 对象

将 JSON 解组为具有唯一元素的 map 切片

JSON 字段的多个名称

根据数据框中的其他列值将列表 json 对象插入行

使用 JQ 从文件中删除重复的 JSON 块

如何在 Go 中生成带有排序键的 JSON?

如何使用 Serde 使用顶级数组反序列化 JSON?

如何使用 gson 调用默认反序列化

Qt使用QJsonDocument、QJsonObject、QJsonArray解析JSON

Java循环遍历Json数组?

为不同类型的项目数组正确的 JSON Schema

将 JSON 模式转换为 python 类

如何在所有子项中查询具有特定值的属性的firebase