Pourquoi est-ce que je deviens inattendu ConvertTo-Json
résultats, pourquoi obtenir des valeurs comme System.Collections.Hashtable
et/ou pourquoi un aller-retour ($Json | ConvertFrom-Json | ConvertTo-Json
) échouer?
Stackoverflow a un bon mécanisme pour éviter les questions en double mais pour autant que je puisse voir, il n'y a pas de mécanisme pour empêcher les questions qui ont un double cause . Prenons cette question comme exemple: presque chaque semaine, une nouvelle question arrive avec la même cause, mais il est souvent difficile de la définir comme un doublon car la question elle-même est juste légèrement différente. Néanmoins, je ne serais pas surpris si cette question/réponse elle-même finit en double (ou hors sujet) mais malheureusement, stackoverflow n'a pas la possibilité de écrire un article pour empêcher d'autres programmeurs de continuer à écrire des questions causée par cet écueil "connu".
Quelques exemples de questions similaires avec la même cause commune:
Alors, est-ce que cette question "auto-répondue" diffère des doublons ci-dessus?
.
ConvertTo-Json
a un -Depth
paramètre:
Spécifie combien de niveaux d'objets contenus sont inclus dans la représentation JSON.
La valeur par défaut est 2 .
Pour effectuer un aller-retour complet avec un fichier JSON, vous devez augmenter le -Depth
pour le ConvertTo-Json
applet de commande:
$Json | ConvertFrom-Json | ConvertTo-Json -Depth 9
Probablement parce que ConvertTo-Json
termine les branches plus profondes que la valeur par défaut -Depth
( 2 ) avec un nom de type complet (.Net), les programmeurs supposent un bogue ou une limitation d'applet de commande et ne lisent pas l'aide ou à propos.
Personnellement, je pense qu'une chaîne avec un simple Ellipsis (trois points:…) à la fin de la branche coupée, aurait un sens plus clair (voir aussi: Problème Github: - 8381 )
Ce problème se retrouve souvent dans une autre discussion également: Pourquoi la profondeur est-elle limitée?
Certains objets ont des références circulaires, ce qui signifie qu'un objet enfant pourrait faire référence à un parent (ou l'un de ses grands-parents) provoquant une boucle infinitive s'il était sérialisé en JSON.
Prenons par exemple la table de hachage suivante avec une propriété parent
qui fait référence à l'objet lui-même:
$Test = @{Guid = New-Guid}
$Test.Parent = $Test
Si vous exécutez: $Test | ConvertTo-Json
il s'arrêtera commodément à un niveau de profondeur de 2 par défaut:
{
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": {
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": {
"Guid": "a274d017-5188-4d91-b960-023c06159dcc",
"Parent": "System.Collections.Hashtable"
}
}
}
C'est pourquoi ce n'est pas une bonne idée de définir automatiquement le -Depth
à un montant élevé.
Vos questions et réponses utiles illustrent clairement à quel point la douleur est la valeur par défaut actuelle ConvertTo-Json
le comportement est.
Quant à la justification du comportement:
Tandis que -Depth
peut être utile pour intentionnellement tronquer une arborescence d'objets d'entrée dont vous n'avez pas besoin de toute la profondeur,-Depth
par défaut à 2
et troncature silencieuse la sortie équivaut à échec de facto silencieux de la sérialisation du point de vue de l'utilisateur sans méfiance - échec qui ne pourra être découvert que plus tard.
La troncature apparemment arbitraire et silencieuse surprend la plupart des utilisateurs et doit en tenir compte dans chaque ConvertTo-Json
l'appel est une charge inutile.
J'ai créé ce problème GitHub pour demander de changer le comportement actuel, en particulier comme suit:
Ignorer -Depth
pour [pscustomobject]
graphes d'objets (une hiérarchie de ce qui est conceptuellement des DTO (objets de transfert de données, "sacs de propriétés"), tels que renvoyés par Convert*From*-Json
), en particulier.
Il le fait est logique d'avoir une limite de profondeur automatique pour types .NET arbitraires, car ils peuvent être des graphiques d'objets de profondeurs excessives et peuvent même contenir des références circulaires; par exemple., Get-ChildItem | ConvertTo-Json
peut devenir rapidement incontrôlable, avec -Depth
valeurs aussi basses que 4
.
Notez que les collections imbriquées, y compris les tables de hachage, ne sont pas elles-mêmes soumises à la limite de profondeur uniquement leurs (scalaires) éléments.
Cette distinction entre les DTO et les autres types est en fait utilisée par PowerShell lui-même dans les coulisses, à savoir dans le contexte de la sérialisation pour à distance et emplois d'arrière-plan.
Utilisation de -Depth
n'est alors nécessaire que pour intentionnellement tronquer l'arborescence des objets d'entrée à la profondeur spécifiée ou sérialiser à un niveau plus profond (si nécessaire si à une profondeur supérieure à la limite de profondeur maximale interne, 100
)
Faites entendre votre voix là , si vous souhaitez voir ce changement se produire (ou en désaccord).