成功调用RestMethod导致选择对象数据失败

时间:2019-07-06 19:13:38

标签: json powershell psobject select-object

我正在使用Invoke-RestMethod -Uri https://...拨打休息服务电话。可以将JSON中的调用结果通过管道传输到Format-Table -Property ...并显示数据。

但是,如果在调用之后使用相同参数的Select-Object -Property ...,则PSObject有列,但没有数据。如果我使用其他Web服务,则该呼叫将正常工作。

enter image description here

是什么导致PSObject不显示任何值?


关于公共休息Web服务的工作示例

Invoke-RestMethod -Uri https://jsonplaceholder.typicode.com/todos/1 |
Select-Object -Property title

结果

@{title=delectus aut autem}

新的故障不同API

Invoke-RestMethod -Uri https://cat-fact.herokuapp.com/facts | Select-Object -Property text

enter image description here

2 个答案:

答案 0 :(得分:3)

第二个示例中的问题是没有名为text的道具。 [咧嘴]

唯一的道具是all,它包含一个对象数组,这些对象确实包含一个名为text的道具。因此,您需要能够获得更深入支持的东西。一种方法是使用两个Select-Object调用。像这样的东西

$Url = 'https://cat-fact.herokuapp.com/facts'
$RawIRM = Invoke-RestMethod -Uri $Url 
$SO_IRM = $RawIRM |
    Select-Object -ExpandProperty all |
    Select-Object -Property text

$SO_IRM var现在具有一个关于猫的178个字符串的数组。 [咧嘴]

答案 1 :(得分:3)

在转换JSON 数组时,您偶然发现了两种PowerShell奇怪的组合:

  • Invoke-RestMethodConvertFrom-Json通过管道发送从JSON转换的数组作为一个整体,而不是按元素元素< / em>,照常

  • Select-Object不执行member enumeration,因此它直接在数组上查找指定的属性(例如text 不存在。

用一个简单的例子演示问题

# Because ConvertFrom-Json sends an *array* (of 2 custom objects) through
# the pipeline, Select-Object looks for property .text on the *array* -
# and can't find it.
# The same applies to Invoke-RestMethod
PS> ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]' | Select-Object text

text
----
       # NO VALUES 

简单的解决方法是将ConvertFrom-Json / Invoke-RestMethod调用括在(...)中,这会强制对数组进行枚举,导致Select-Object正常工作。:

# (...) forces enumeration
PS> (ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]') | Select-Object text

text
----
a
b

请注意,诸如Select-Object -Property text(无-ExpandProperty)之类的命令仍会输出具有.text属性的自定义对象,而不是.text属性

如果您只对属性 values 感兴趣,那么解决方案会更简单,因为您可以直接在数组上使用上述成员枚举:

# Using .<propName> on an array (collection) implicitly returns the
# property values from the *elements* of that collection (member enumeration).
PS> (ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]').text
a
b

请注意,输出现在没有text标头,因为输出的只是字符串值,而不是自定义对象。