なぜ予期しない結果になるのですか ConvertTo-Json
結果、なぜSystem.Collections.Hashtable
および/または往復($Json | ConvertFrom-Json | ConvertTo-Json
) 不合格?
Stackoverflowは重複questionsを防止するための優れたメカニズムを備えていますが、私が見る限り、重複原因。この質問を例に取ってみましょう。ほぼ毎週新しい質問が同じ原因で発生しますが、質問自体がわずかに異なるだけなので、それを重複として定義することはしばしば困難です。それでも、この質問/回答自体が重複(またはトピック外)になったとしても驚くことはありませんが、残念ながら、stackoverflowで 記事を書く が他のプログラマーが質問を書き続けるのを防ぐことができません。この「既知の」落とし穴が原因です。
同じ一般的な原因を持つ同様の質問のいくつかの例:
では、この「自己回答」の質問は上記の重複とは違うのでしょうか。
タイトルには共通の原因があり、同じ原因による質問の繰り返しを防ぐ方がよい場合があります。
ConvertTo-Json
には-Depth
パラメータがあります:
JSON表現に含まれるオブジェクトのレベル数を指定します。
default の値は 2 です。
JSONファイルで完全なラウンドトリップを行うには、-Depth
コマンドレットのConvertTo-Json
を増やす必要があります。
$Json | ConvertFrom-Json | ConvertTo-Json -Depth 9
おそらくConvertTo-Json
は、デフォルトの-Depth
( 2 )より深いブランチを(.Net)完全型名で終了するため、プログラマはバグまたはコマンドレットの制限。ヘルプなどについては読みません。
個人的には、カットオフブランチの末尾に単純な Ellipsis (3つのドット:…)が付いた文字列は、より明確な意味を持つと思います(Githubの問題も参照:- 8381 )
この問題は多くの場合、別のディスカッションでも終わります:なぜ深さが制限されているのですか?
一部のオブジェクトには循環参照があります。つまり、子オブジェクトが親(またはその祖父母の1つ)を参照する可能性があり、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
を自動的に大量に設定することはお勧めできません。
役立つ質問と回答は、現在のデフォルトのConvertTo-Json
の動作がどれほど問題になるかを明確に示しています。
動作の justification について:
-Depth
は、意図的に必要のない完全な深さの入力オブジェクトツリーを切り捨てるのに役立ちますが、-Depth
defaulting to 2
and quietly truncating 出力量は疑いを持たないユーザーの観点からのシリアル化の静かな事実上の失敗-後でないと発見できない可能性のある失敗。
ほとんどのユーザーにとって一見恣意的で静かな切り捨ては驚くべきことであり、すべてのConvertTo-Json
呼び出しでそれを考慮する必要があることは不必要な負担です。
私は このGitHubの問題 を作成して、具体的には次のように現在の動作の変更を要求します。
特に、-Depth
から返された[pscustomobject]
オブジェクトグラフ(概念的にはDTO(データ転送オブジェクト、「プロパティバッグ」)の階層)のConvert*From*-Json
を無視します。
does arbitrary .NET types 、深すぎるオブジェクトグラフである可能性があり、循環参照が含まれる場合さえある。たとえば、Get-ChildItem | ConvertTo-Json
の値は-Depth
と同じくらい低いため、4
はすぐに手に負えなくなります。
ネストされた collections (ハッシュテーブルを含む)自体は、(スカラー) elements のみの深さ制限の対象ではないことに注意してください。
DTOと他のタイプのこの区別は、実際にはPowerShell自体の裏側で使用されています、つまり remoting のシリアル化のコンテキストでおよび background jobs 。
次に、-Depth
の使用は、意図的に入力オブジェクトツリーを指定された深度で切り捨てるか、より深いレベルにシリアル化するためにのみ必要です(内部の最大深度の制限よりも深い場合は、 100
)
あなたの声を聞かせてください there 、この変化が起こるのを見たい(または同意しない)場合。