PowerShell 7 处理嵌套 JSON:解析成功,不代表序列化完整
处理云 API 的请求体或响应时,经常需要把 JSON 转成对象,修改后再输出。PowerShell 7 中有一个容易忽略的区别:ConvertFrom-Json 默认最大解析深度为 1024,而 ConvertTo-Json 默认序列化深度为 2。解析成功,不保证再次序列化时嵌套结构仍然完整。
下面使用完全虚构的通用 JSON,字段不对应任何云平台接口;示例只在本机运行,不访问网络、账号或凭证。验证环境是 Windows 11 和 PowerShell 7.6.7。整段代码可直接复制执行,不创建临时文件。
$json = '{"demo":{"level1":{"level2":{"value":3}}}}'
$obj = $json | ConvertFrom-Json
"解析值: $($obj.demo.level1.level2.value)"
$bad = $obj | ConvertTo-Json -Compress
"默认结果: $bad"
$badObj = $bad | ConvertFrom-Json
"默认 level2 类型: $($badObj.demo.level1.level2.GetType().Name)"
$good = $obj | ConvertTo-Json -Depth 10 -Compress -WarningAction Stop
$round = $good | ConvertFrom-Json
"修复结果: $good"
"修复后的值: $($round.demo.level1.level2.value)"
if ($round.demo.level1.level2 -isnot [PSCustomObject] -or
$round.demo.level1.level2.value -ne 3) {
throw '往返校验失败'
}
'往返校验: 通过'
本机实际输出:
解析值: 3
WARNING: Resulting JSON is truncated as serialization has exceeded the set depth of 2.
默认结果: {"demo":{"level1":{"level2":"@{value=3}"}}}
默认 level2 类型: String
修复结果: {"demo":{"level1":{"level2":{"value":3}}}}
修复后的值: 3
往返校验: 通过
默认输出仍是合法 JSON,但其中的 level2 已从对象变成字符串 "@{value=3}"。原来的 $obj 并未改变,出问题的是重新生成的 JSON;把它当请求体提交,字段类型就可能不符合接口要求。PowerShell 7.1 起,序列化超过设定深度时会发出警告,因此不要忽略或屏蔽这类警告。
两个命令的 -Depth 同名,控制的环节却不同:前者限制输入 JSON 允许的最大嵌套深度,后者控制输出时展开对象的层数。把解析深度调大,并不能代替为序列化命令设置深度。反过来,如果手动将解析深度设得太小,解析会报错,属于另一个需要检查的问题。
修复时,根据实际结构给 ConvertTo-Json 指定足够的 -Depth,上面的 10 只是示例,不是所有数据都适用的固定值;该参数允许 0 到 100。这里还使用 -WarningAction Stop,让警告中止执行,避免后续步骤继续使用不完整的结果。它会对该命令的其他警告同样生效。
最后再解析输出,检查关键字段的类型和值;真实业务还应按接口约定检查必填字段、数组和取值范围。示例只验证了一条路径,并不能证明更复杂的对象中所有字段都正确。实际测试应覆盖不同层级,尤其是嵌套数组及其元素;只检查最外层字段,很容易漏掉深层变化。
深度足够也不意味着 JSON 文本会逐字保持不变,格式和属性排列都不应作为完整性判断的唯一依据。排查真实请求时,也不要把令牌或敏感数据直接写进日志。
本文由 Hermes AI 协助编写,示例与输出均在本机验证。
- 点赞
- 收藏
- 关注作者
评论(0)