为什么会得到意外的ConvertTo-Json
结果,为什么会得到类似System.Collections.Hashtable
的值和/或为什么往返($Json | ConvertFrom-Json | ConvertTo-Json
)失败?
meta问题
Stackoverflow有一个很好的机制来防止重复的问题,但据我所知,没有机制来防止有重复的原因的问题。以这个问题为例:几乎每周都会有一个新问题出现,原因相同,但通常很难将其定义为重复,因为问题本身只是略有不同。然而,如果这个问题/答案本身最终是重复的,我不会感到惊讶(或离题),但不幸的是,stackoverflow不可能write an article来阻止其他程序员继续编写由此引起的问题“已知”陷阱“。
重复
以下是一些具有相同共同原因的类似问题的示例:
- PowerShell ConvertTo-Json does not convert Array as expected(昨天)
- Powershell ConvertTo-json with embedded hashtable
- powershell “ConvertTo-Json” has messed json format output
- Nested arrays and ConvertTo-Json
- Powershell ConvertTo-JSON missing nested level
- How to save a JSON object to a file using Powershell?
- Cannot convert PSCustomObjects within array back to JSON correctly
- ConvertTo-Json flattens arrays over 3 levels deep
- Add an array of objects to a PSObject at once
- Why does ConvertTo-Json drop values
- How to round-trip this JSON to PSObject and back in Powershell
- ...
与众不同
那么,这个“自我回答”的问题与上面的重复问题有什么不同呢?
它在标题中有共同的原因,这样可以更好地防止由于同一原因而重复问题。
2条答案
按热度按时间ewm0tg9j1#
答案
ConvertTo-Json
有一个**-Depth
**参数:指定JSON表示中包含的对象的级别数。
默认值为2。
示例
要对JSON文件执行完整的往返操作,您需要为
ConvertTo-Json
cmdlet增加-Depth
:靶区;DR
可能是因为
ConvertTo-Json
使用(.Net)完整类型名称终止比默认-Depth
(2)更深的分支,程序员假定存在错误或cmdlet限制,而不阅读帮助或about。我个人认为,一个字符串如果包含一个简单的ellipsis(三个点:...)在年底切断分支,将有一个更明确的含义(另见:Github问题:8381)
为什么?
这个问题通常也会在另一个讨论中结束:为什么要限制深度?
有些对象有循环引用,这意味着子对象可以引用父对象(或其祖对象之一),如果将其序列化为JSON,则会导致无限循环。
以下面的哈希表为例,该哈希表具有引用对象本身的
parent
属性:如果执行:
$Test | ConvertTo-Json
默认情况下,它将方便地停止在深度级别2处:这就是为什么自动将
-Depth
设置为较大值不是一个好主意的原因。u4dcyp6a2#
您的问题和answer清楚地说明了当前默认
ConvertTo-Json
行为的棘手问题。*至于行为的 * 正当理由 :
虽然
-Depth
可以用于 * 有意 * 截断您不需要其完整深度的输入对象树,但**-Depth
* 默认 * 为2
并 * 悄悄地截断 * 输出,从不知情的用户的Angular 来看,相当于序列化的 * 悄悄的事实上的失败**-可能要到以后才能发现的失败。对于大多数用户来说,这种看似随意且安静的截断令人惊讶,而且必须在每次
ConvertTo-Json
调用中考虑它是一种不必要的负担。我创建了GitHub issue #8393,其中包含一个*建议 * 来改变当前行为,具体如下:
*忽略
[pscustomobject]
对象图(概念上为DTO(数据传输对象,“属性包”)的层次结构,例如从Convert*From*-Json
返回的对象)的-Depth
。Get-ChildItem | ConvertTo-Json
可能很快失控,而-Depth
的值低至4
。也就是说,在JSON序列化中使用任意的.NET类型通常是不明智的:JSON并不是为给定平台类型设计的通用序列化格式;相反,它集中在DTO上,仅包含 * 属性 *,具有 * 有限的数据类型集 *。***DTO和其他类型之间的这种区别实际上是由PowerShell本身在 * 幕后 * 使用的,即在 * 远程处理 * 和 * 后台作业***的序列化上下文中。
-Depth
来 * 有意地 * 在指定深度截断输入对象树(或者,大多数情况下假设,为了序列化到比内部最大深度限制100
更深的级别)。