Как прочитать JSON со свойствами #type и #value в 1С без ошибки недопустимого имени свойства?

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

При интеграции между базами 1С через HTTP-сервисы или веб-сервисы часто передаются данные, полученные стандартной сериализацией платформы. В таком формате JSON содержит служебные имена полей со знаком решетки, например #type и #value.

Попытка прочитать такой документ стандартной функцией ПрочитатьJSON() без дополнительных параметров приводит к ошибке выполнения: Недопустимое имя Свойства: "#type" для чтения JSON в объект Структура. Разберем причины возникновения этой ошибки и выясним, какими способами можно корректно прочитать входящие данные.

Посмотрим на пример входящего JSON-пакета, который вызывает исключение:


{
  "#type": "jcfg:CatalogObject.КакойтоСправочник",
  "#value": {
    "IsFolder": false,
    "Ref": "eb04c6b2-fdb7-11e6-8046-000c29123d1d",
    "DeletionMark": false,
    "Code": "000000000001",
    "Description": "Описание"
  }
}

Почему возникает ошибка при чтении в Структуру

Проанализируем механику работы метода ПрочитатьJSON(). По умолчанию платформа 1С пытается преобразовать все объекты JSON в коллекцию Структура. Имена ключей в объекте Структура должны строго соответствовать правилам именования переменных встроенного языка 1С: они могут содержать только буквы, цифры и знак подчеркивания, а также не могут начинаться с цифры.

Символ # является недопустимым символом для ключа структуры, поэтому при попытке создать поле #type платформа прерывает выполнение с ошибкой.

Вариант 1. Чтение в коллекцию Соответствие (рекомендуемый способ)

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

В отличие от структуры, ключами коллекции Соответствие могут выступать произвольные строки с любыми спецсимволами, включая #, пробелы, дефисы и точки. Для этого во второй параметр метода ПрочитатьJSON() необходимо передать значение Истина (параметр ПрочитатьВВидеСоответствия).

Разберем пример программного кода:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ИмяФайла);

// Второй параметр "Истина" указывает платформе читать объекты как Соответствие
РезультатJSON = ПрочитатьJSON(ЧтениеJSON, Истина);
ЧтениеJSON.Закрыть();

// Обращение к элементам выполняется через квадратные скобки
ТипОбъекта = РезультатJSON["#type"];
ДанныеОбъекта = РезультатJSON["#value"];

Если ДанныеОбъекта <> Неопределено Тогда
    Код = ДанныеОбъекта["Code"];
    Наименование = ДанныеОбъекта["Description"];
КонецЕсли;

Вариант 2. Использование объекта СериализаторXDTO

Если в текущей информационной базе существует справочник или документ точно с таким же именем и структурой реквизитов, как указано в свойстве #type, можно сразу восстановить исходный объект платформы 1С. Для этого используется системный объект СериализаторXDTO.

Рассмотрим, как прочитать данные через XDTO-десериализацию:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ИмяФайла);

// Восстанавливаем объект конфигурации напрямую
ОбъектСправочника = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

// Если тип совпал, в переменной будет готовый CatalogObject
Если ОбъектСправочника <> Неопределено Тогда
    ОбъектСправочника.Записать();
КонецЕсли;

Важное ограничение: данный способ сработает только в том случае, если тип из #type объявлен в метаданных текущей конфигурации. Если конфигурации источника и приемника различаются, метод вызовет ошибку несоответствия типов XDTO.

Вариант 3. Потоковое чтение через ЧтениеJSON

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

Разберем по шагам логику потокового обхода:

  1. Открываем поток с помощью объекта ЧтениеJSON.
  2. В цикле вызываем метод Прочитать() для последовательного перехода по узлам.
  3. Проверяем свойство ТипТекущегоЗначения на равенство ТипУзлаJSON.ИмяСвойства.
  4. При обнаружении нужного свойства (например, внутри блока #value) считываем его значение.
  5. По окончании обработки обязательно закрываем поток методом Закрыть().

Таким образом, для чтения JSON-структур со служебными префиксами достаточно передать флаг чтения в виде соответствия ПрочитатьJSON(ЧтениеJSON, Истина) либо воспользоваться объектом СериализаторXDTO при наличии идентичных метаданных.

← На главную