为什么我会得到意外的ConvertTo-Json
结果?
Stackoverflow有一个很好的机制来防止重复的问题,但据我所知,还没有一种机制可以防止具有重复原因的问题。以这个问题为例:几乎每个星期都有一个新问题是由相同的原因引起的,但是通常很难将其定义为重复问题,因为问题本身只是稍有不同。 不过,如果这个问题/答案本身以重复(或脱题)结尾,我不会感到惊讶,但是不幸的是,stackoverflow无法write an article来防止其他程序员继续写由“已知”引起的问题。 ”陷阱。
具有相同共同原因的类似问题的一些示例:
那么,这个“自我回答”的问题是否与上述重复问题有所不同?
标题中有共同原因,因此可以更好地防止由于相同原因而重复问题。
答案 0 :(得分:4)
ConvertTo-Json
具有 -Depth
参数:
指定包含在其中的对象的级别数 JSON表示形式。
默认值为 2 。
可能是由于ConvertTo-Json
终止了比默认-Depth
( 2 )更深的分支,并带有(.Net)完整类型名称,程序员可能会认为是错误或cmdlet限制,请勿阅读帮助或关于。
我个人认为,在切除分支的末尾带有简单ellipsis(三个点:…)的字符串将具有更清晰的含义(另请参见:Github问题:8381)
这个问题通常还会在另一个讨论中结束: 为什么深度根本没有限制?
某些对象具有循环引用,这意味着子对象可以引用父对象(或其祖父母之一),如果将其序列化为JSON,则会导致无限循环。
例如,下面的哈希表具有一个指向对象本身的parent
属性:
$Test = @{Guid = New-Guid}
$Test.Parent = $Test
如果执行:$Test | ConvertTo-Json
,默认情况下它将方便地停在2的深度级别:
{
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": {
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": {
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": "System.Collections.Hashtable"
}
}
}
这就是为什么自动将-Depth
设置为大量不是一个好主意的原因。
答案 1 :(得分:1)
您的问题清楚地说明了当前默认ConvertTo-Json
行为带来的痛苦点。
关于行为的合理性:
某些对象具有循环引用
在内部,ConvertTo-Json
实际上具有防止无限深度序列化的安全功能:如果深度超过100
级别,它将报告错误。
此内部限制应该足够。
虽然-Depth
可以用于有意地截断不需要完整深度的输入对象树,但
-Depth
从毫无戒心的用户的角度来看,将默认设置为2
并悄悄地将输出等同于序列化的事实上的失败 -直到后来才发现的故障。
看似随意且安静的截断对于大多数用户来说是令人惊讶的,并且每次ConvertTo-Json
调用中都要考虑它是不必要的负担。
我已创建this GitHub issue来请求更改当前行为,具体如下:
删除-Depth
的默认值
100
的硬编码内部限制(超过该限制时会报告错误),足以防止源于带有循环依赖关系的对象束的“失控” JSON字符串。根据用户的判断,仅使用-Depth
来
100
级更深的对象树。如果您希望看到这种变化的发生(或不同意),请在此听到您的声音。