Неожиданные результаты ConvertTo-Json? Ответ: по умолчанию - Глубина 2

Почему я получаю неожиданное ConvertTo-Json Результаты?

Мета выпуск

В Stackru есть хороший механизм предотвращения повторяющихся вопросов, но, насколько я вижу, нет механизма предотвращения повторяющихся вопросов. Возьмите этот вопрос в качестве примера: почти каждую неделю появляется новый вопрос с одной и той же причиной, но зачастую трудно определить его как дубликат, потому что сам вопрос немного отличается. Тем не менее, я не удивлюсь, если сам этот вопрос / ответ окажется дубликатом (или не по теме), но, к сожалению, stackru не имеет возможности написать статью, чтобы помешать другим программистам продолжать писать вопросы, вызванные этой "известной" ошибкой,

Дубликаты

Несколько примеров похожих вопросов с той же общей причиной:

Разные

Так чем же этот вопрос с "самоотвечением" отличается от приведенных выше дубликатов?
У него есть общая причина в названии, и это может лучше предотвратить повторение вопросов по той же причине.

3 ответа

Ответ

ConvertTo-Json имеет -Depth параметр:

Указывает, сколько уровней содержащихся объектов включено в представление JSON.
Значением по умолчанию является 2.

TL; DR

Наверное потому что ConvertTo-Json завершает ветви, которые глубже, чем по умолчанию -Depth (2) с полным именем типа (.Net) программисты принимают ошибку или ограничение командлета и не читают справку или информацию о ней.
Лично я думаю, что строка с простым многоточием (три точки: …) в конце обрезанной ветви будет иметь более ясное значение (см. Также: выпуск 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 в большом количестве.

Ваш вопрос ясно показывает, насколько болевые точки соответствуют текущим значениям по умолчанию. ConvertTo-Json поведение есть.

Что касается обоснования поведения:

Некоторые объекты имеют циклические ссылки

Внутренне ConvertTo-Json на самом деле имеет функцию безопасности, которая предотвращает бесконечно глубокую сериализацию: она сообщает об ошибке, если глубина превышает 100 уровни.

Этого внутреннего предела должно быть достаточно.

В то время как -Depth может быть полезным для преднамеренного усечения дерева входных объектов, полная глубина которого вам не нужна,
-Depth по умолчанию 2 и тихое усечение вывода означает тихий фактический сбой сериализации с точки зрения ничего не подозревающего пользователя - сбой, который может быть обнаружен только позже.

Казалось бы, произвольное и тихое усечение удивляет большинство пользователей, и приходится учитывать его в каждом ConvertTo-Json Звонить - это ненужное бремя.

Я создал эту проблему GitHub, чтобы запросить изменение текущего поведения, а именно:

  • Удалить значение по умолчанию для -Depth

    • Жестко закодированный внутренний предел 100 При превышении которого выдается сообщение об ошибке, этого достаточно, чтобы предотвратить "убегающие" строки JSON, возникающие из-за тресса объекта с циклическими зависимостями.
    • Типичные входные объекты будут полностью сериализованы по умолчанию, что обычно является намерением.
  • использование -Depth исключительно по усмотрению пользователя для того, чтобы:

    • Умышленное усечение дерева входных объектов на заданной глубине.
    • В редких случаях разрешите сериализацию деревьев объектов, которые глубже, чем 100 уровни.

Сделайте так, чтобы ваш голос был услышан там, если вы хотите, чтобы это изменение произошло (или не согласилось).

.. | ConvertTo-Json -Depth 100 | ..

Максимальная глубина — 100 в последней версии PowerShell (моя: 7.3.4, переименована в PowerShell Core).

Другие вопросы по тегам