使用Powershell从Json结构提取值时出现问题

使用Powershell从Json结构提取值时出现问题,json,powershell,Json,Powershell,使用Powershell,我将一个json片段返回到我的第一个变量中(这总是很好) 然后我将convert函数调用为一个temp变量,如下所示 $ResponseBody = ConvertFrom-Json $whatStatusJsonContent; message_id ---------- 9093813071099257562 它将Json放入这样一个漂亮的小数据结构中 $ResponseBody = ConvertFrom-Json $wha

使用Powershell,我将一个json片段返回到我的第一个变量中(这总是很好)

然后我将convert函数调用为一个temp变量,如下所示

$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
         message_id
         ----------
9093813071099257562
它将Json放入这样一个漂亮的小数据结构中

$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;
         message_id
         ----------
9093813071099257562
我可以通过调用此函数从中选择所需的值

$nMessage_id = $ResponseBody.message_id;
通常,这很好,我将值放入第二个变量中

$nMessage_id = 9093813071099257562
问题是:有时我在$nMessage_id中什么也得不到,即使$whatStatusJsonContent肯定被记录为从函数正确返回了Json

我的问题是:我必须从Json转换,还是可以从第一个变量中读取原始值

组合解决方案:感谢@mklement()和@Bernard Moeskops

# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'

$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;

if($ResponseBody.message_id){
    # ConvertFrom-Json got the value!
    $nMessage_id = $ResponseBody.message_id
}else{
    # ConvertFrom-Json didn't work!
    $nMessage_id = = ($whatStatusJsonContent -split '[:}]')[1]
}

您必须转换它,以便PowerShell能够理解它。它将从字符串转换为PSCustomObject。只需询问前后变量的类型即可进行检查

$ResponseBody.message_id.GetType()
如果有时输出为空,则可以执行以下操作:

if($ResponseBody.message_id){
    $nMessage_id = $ResponseBody.message_id
}else{
    throw "No message id found"
}

希望这有帮助。

您的代码没有明显的错误

应按预期工作,并返回带有
.message\u id
属性的
[pscustomobject]
实例

在您的示例中,
message\u id
JSON属性值是一个整数,对于它,
ConvertTo JSON
自动选择一个合适的整数数据类型,如下所示:最小的有符号类型>=
[int]
System.Int32
)[1],它可以容纳值(
[int]
->
[long]
System.Int64
)->
[decimal]
System.decimal
);需要注意的是,如果该值甚至不能放入
[decimal]
,则使用-increact-
[double]
。[2]

对于问题中的示例JSON,选择了
[long]

在后续评论中,您声明:

该例程每小时发出1000多个调用,对于大多数调用来说,Json会返回,
$nMessage_id
生成得非常完美。然后,突然间,
$nMessage_id
为空,即使Json被记录为恢复正常。因此,在Json的
转换器
$ResponseBody.message_id
中的某个地方,该值将丢失

我没有解释,但如果(无论出于何种原因,
convertfromjson
是罪魁祸首,您可以尝试字符串操作作为一种解决方法来提取消息ID,看看这是否有帮助:

$whatStatusJsonContent = '{"message_id":9093813071099257562}'

# Extract the message_id property value as a *string*  
# (which you can cast to a numeric type if/as needed).  
$message_id = ($whatStatusJsonContent -split '[:}]')[1]
上面在
$message_id
中存储内容为
9093813071099257562
的字符串;请注意,正如所写的,输入字符串的格式必须与上面关于空格的格式完全相同;虽然可以使文本解析更加健壮,但不必担心格式变化是使用专用解析器(如
convertfromjson
)的一个很好的理由


另一个选项是尝试另一个JSON解析器,看看这是否有帮助。 是.NET世界中卓越的JSON解析器(现在是PowerShell Core中JSON cmdlet的基础):

注意:Json.NET类似于PowerShell内核中Json的
转换,当一个数字太大而无法放入
[long]
时,它也可以使用任意大的
[bigint]
类型

使用Json.NET程序集比使用
ConvertFrom-Json
cmdlet具有更好的性能

在PowerShell Core中,可以按原样运行上述代码(程序集已预加载);在Windows PowerShell中,您必须通过上面的链接下载程序包,并使用
add Type-LiteralPath
将程序集(
NewtonSoft.Json.dll
)添加到会话中


[1] 奇怪的是,在PowerShell Core中,从(至少)v6.2.0开始,选择的最小类型是
[long]
System.Int64


[2] 更有用的是,从(至少)v6.2.0开始,PowerShell Core会在值不再适合
[long]
时创建一个任意大的
[bigint]
System.Numerics.biginger
)实例;也就是说,完全跳过了
[decimal]
类型。

我非常怀疑这是问题所在。我认为在变量为空时,它实际上不会返回任何数据。。您需要做的是使用Powershell_ise.exe,并确保在脚本中添加以下内容如果(!$ResponseBody.message_id){Write Host“响应主体为空”}#现在在Write Host部分放置一个制动点(F9)。运行脚本,身体一空,你就会到达制动点。现在脚本暂停,您可以使用空的特定调用进行故障排除。希望这对我有所帮助,如果我需要进一步澄清,请告诉我。我唯一能想象的是,由于连接中断或其他原因,每一百万次回复都是空的?时代。当给定有效输入时,Json的ConvertFrom将始终工作。如果某个程序是固态编写的,它不会失败。然而,调用API有很多依赖关系。在您的情况下,很难排除故障。网络相关问题显然是罪魁祸首。您可以尝试收集更多的$ResponseBy.message_id,例如StatusCode,以及任何与例如200不同的时间来输出响应/错误。感谢@Bernard Moeskops的帮助,请参阅组合解决方案感谢@rangi;我很高兴你找到了一个有效的解决办法。了解问题的真正原因仍然是一件有趣的事情,例如,是否有一个来自Json的
ConvertFrom
bug;您是否尝试过Json.NET替代方案,这样您就不必依赖文本解析了?如果有机会,我会尝试一下,这有点棘手,因为我可能无法将包上载到Azure无服务器环境中。干杯