Как обернуть массив JSON в фигурные скобки в 1С и избежать ошибок валидации

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С со сторонними веб-сервисами и мобильными приложениями разработчики часто сталкиваются со специфическими требованиями к формату обмена данными. Одна из классических ситуаций — когда принимающая сторона ожидает получить данные в некорректном с точки зрения стандартов формате, например, обернуть массив объектов в «пустые» фигурные скобки без указания имени свойства: {[ ... ]}.

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

Анализ проблемы: почему конструкция {[ ... ]} невалидна

Давайте разберем по шагам, что представляет собой формат JSON согласно международному стандарту RFC 8259. Данный формат поддерживает два основных типа коллекций:

  1. Объект (коллекция пар «ключ - значение»). Ограничивается фигурными скобками { }. Внутри объекта обязательно должны находиться свойства в формате "ИмяСвойства": Значение, разделенные запятыми.
  2. Массив (упорядоченный список значений). Ограничивается квадратными скобками [ ]. Значения в нем могут быть строками, числами, объектами или другими массивами, но они пишутся через запятую без ключей.

Когда мы пытаемся записать конструкцию вида {[ ... ]}, мы создаем объект (фигурные скобки), внутри которого сразу же располагается массив (квадратные скобки), минуя имя свойства. Такой формат является грубым нарушением стандарта JSON. Любой стандартный валидатор или встроенный парсер на веб-сайте выдаст ошибку: "Invalid JSON format".

Если в коде 1С попытаться записать такую структуру с помощью встроенного объекта ЗаписьJSON при стандартных настройках:


ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьНачалоМассива(); // Здесь платформа вызовет исключение!

Платформа 1С сразу прервет выполнение программы с ошибкой структуры, так как свойство ПроверятьСтруктуру у объекта записи по умолчанию установлено в значение Истина.

Рассмотрим, как правильно решить эту техническую задачу тремя разными способами.

Решение 1. Правильный переход к объектной модели (Best Practice)

Если у вас есть возможность повлиять на разработчика принимающей стороны (веб-сайта), настоятельно рекомендуется убедить его использовать валидный JSON. Вместо генерации структуры вручную через последовательную запись свойств (потоковый метод), в 1С гораздо проще, быстрее и безопаснее использовать объектную сериализацию.

Давайте проанализируем, как переписать исходный алгоритм автора. Вместо ручного вызова методов ЗаписатьНачалоОбъекта и ЗаписатьИмяСвойства, мы соберем данные в стандартные коллекции 1С: Массив и Структура, после чего выгрузим их одной командой ЗаписатьJSON.

Для создания валидного JSON-объекта, содержащего внутри себя массив, мы дадим этому массиву понятное имя (ключ), например, "contracts". Посмотрим на пример кода:


// 1. Создаем массив для хранения наших объектов-договоров
МассивДоговоров = Новый Массив;

// Предположим, у нас есть выборка данных ВыборкаДог
Пока ВыборкаДог.Следующий() Цикл
    
    // Каждую запись оформляем в виде отдельной структуры
    ДоговорОбъект = Новый Структура;
    
    // ВАЖНО: Ключи должны быть статичными, без добавления счетчиков (ContractNumber, а не ContractNumber1)
    ДоговорОбъект.Вставить("ContractNumber", Строка(ВыборкаДог.Contract.Номер));
    ДоговорОбъект.Вставить("ContractDate", ВыборкаДог.Contract.Дата);
    
    МассивДоговоров.Добавить(ДоговорОбъект);
    
КонецЦикла;

// 2. Оборачиваем массив в структуру верхнего уровня для создания правильного объекта {}
ДанныеДляЭкспорта = Новый Структура;
ДанныеДляЭкспорта.Вставить("contracts", МассивДоговоров);

// 3. Выполняем быструю сериализацию в строку
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(, Символы.Таб);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);

// Сериализуем объект целиком одной командой
ЗаписатьJSON(ЗаписьJSON, ДанныеДляЭкспорта);

СтрJSON = ЗаписьJSON.Закрыть();

В результате работы данного алгоритма мы получим красивый, структурированный и, самое главное, абсолютно валидный JSON-код:


{
	"contracts": [
		{
			"ContractNumber": "XC000265Y",
			"ContractDate": "2013-08-10T00:00:00"
		},
		{
			"ContractNumber": "XC01691LY",
			"ContractDate": "2018-06-10T00:00:00"
		}
	]
}

Обратите внимание: мы передали тип Дата напрямую в структуру без принудительного преобразования через функцию Строка(). Платформа 1С автоматически сериализовала дату в международный стандарт ISO 8601. Это значительно облегчит парсинг данных на стороне веб-сервиса.

Решение 2. Отключение проверки структуры (если "очень нужно" нарушить стандарт)

Бывают ситуации, когда принимающий веб-сервер написан на коленке, его исходный код недоступен для изменений, а разработчик со стороны контрагента настаивает на формате {[ ... ]}.

Чтобы обойти строгие правила 1С и записать невалидный JSON программным путем, мы можем временно отключить валидацию структуры в объекте ЗаписьJSON. Для этого используется свойство ПроверятьСтруктуру. Рассмотрим этот пример подробнее:


ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(, Символы.Таб);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);

// Отключаем встроенную валидацию структуры платформы
ЗаписьJSON.ПроверятьСтруктуру = Ложь;

// Начинаем вывод невалидного набора скобок
ЗаписьJSON.ЗаписатьНачалоОбъекта(); // Записывает "{"
ЗаписьJSON.ЗаписатьНачалоМассива();  // Записывает "[" без ключа! Платформа промолчит.

Пока ВыборкаДог.Следующий() Цикл
    
    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    
    // Внутренние свойства объектов записываем в стандартном режиме
    ЗаписьJSON.ЗаписатьИмяСвойства("ContractNumber");
    ЗаписьJSON.ЗаписатьЗначение(Строка(ВыборкаДог.Contract.Номер));
    
    ЗаписьJSON.ЗаписатьИмяСвойства("ContractDate");
    ЗаписьJSON.ЗаписатьЗначение(Формат(ВыборкаДог.Contract.Дата, "ДФ=yyyy-MM-dd"));
    
    ЗаписьJSON.ЗаписатьКонецОбъекта();
    
КонецЦикла;

ЗаписьJSON.ЗаписатьКонецМассива();  // Записывает "]"
ЗаписьJSON.ЗаписатьКонецОбъекта();  // Записывает "}"

РезультатСтрокой = ЗаписьJSON.Закрыть();

Этот метод позволяет добиться нужной последовательности скобок {[ ... ]} непосредственно при генерации потока. Однако помните, что такое решение является "костылем" и нарушает общую логику работы с форматом обмена данными.

Решение 3. Постобработка строки (безопасная ручная сборка)

Если вы не хотите отключать проверку структуры у ЗаписьJSON (чтобы случайно не пропустить другие критические ошибки в процессе разработки), самым простым и безопасным решением будет формирование стандартного валидного массива с его последующей текстовой оберткой.

Выясним причину, почему это безопаснее: мы поручаем платформе собрать валидный JSON-массив, гарантируя отсутствие синтаксических ошибок, а затем просто дописываем нужные символы по краям строки методами работы с текстом.

Разберем данный подход по шагам:


// Шаг 1. Формируем валидный массив объектов стандартным способом
МассивОбъектов = Новый Массив;

Пока ВыборкаДог.Следующий() Цикл
    ДоговорОбъект = Новый Структура("ContractNumber, ContractDate");
    ДоговорОбъект.ContractNumber = Строка(ВыборкаДог.Contract.Номер);
    ДоговорОбъект.ContractDate = Формат(ВыборкаДог.Contract.Дата, "ДФ=dd.MM.yyyy");
    
    МассивОбъектов.Добавить(ДоговорОбъект);
КонецЦикла;

// Шаг 2. Сериализуем массив в строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(Новый ПараметрыЗаписиJSON(, Символы.Таб));
ЗаписатьJSON(ЗаписьJSON, МассивОбъектов);
СтандартныйJSON = ЗаписьJSON.Закрыть();

// СтандартныйJSON на данный момент выглядит так:
// [
//     { "ContractNumber": "...", ... }
// ]

// Шаг 3. Вручную оборачиваем полученный текст в фигурные скобки
НестандартныйJSON = "{" + Символы.ПС + СтандартныйJSON + Символы.ПС + "}";

Используя этот прием, вы гарантируете себе корректную работу сериализатора 1С во время сборки основного массива и одновременно полностью удовлетворяете специфическое требование принимающей стороны, обернув результат в фигурные скобки на самом последнем этапе.

Важные рекомендации по работе с JSON в 1С

Для того чтобы ваш код интеграции всегда оставался чистым и легко поддерживаемым, старайтесь следовать следующим правилам:

← На главную