Как исправить ошибку XDTO "НачалоСвойства: Ref Форма: Элемент Тип: string" при чтении JSON?

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

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

Ошибка преобразования данных XDTO: НачалоСвойства: Ref Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}string

Давайте подробно разберем, почему возникает эта ошибка, что она означает с технической точки зрения и какие существуют способы ее устранения. Мы проанализируем ситуацию, начиная от проверки кода и заканчивая особенностями метаданных конфигурации.

Понимание сути ошибки

Прежде чем переходить к решениям, давайте расшифруем сообщение системы. Сериализатор XDTO (XML Data Transfer Objects) работает на основе схем данных. В 1С любой ссылочный объект (Справочник, Документ) имеет стандартное описание в глобальной фабрике XDTO.

Ошибка сообщает нам о конфликте ожиданий и реальности:

  1. НачалоСвойства: Ref — парсер дошел до свойства, отвечающего за ссылку (Reference) или идентификацию объекта.
  2. Форма: Элемент — согласно схеме XDTO, здесь ожидается вложенный элемент (сложная структура).
  3. Тип: string — а в реальных данных (в файле JSON) парсер обнаружил простую строку.

Или наоборот, в зависимости от контекста: ожидалась строка (UUID), а пришел объект. Этот конфликт блокирует дальнейшее чтение данных.

Причина 1: Десериализация в другой информационной базе

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

Разберем эту ситуацию подробнее. Когда мы используем глобальный СериализаторXDTO, он опирается на метаданные текущей конфигурации. Если вы записали объект справочника в файл JSON в Базе А, а затем пытаетесь прочитать его через СериализаторXDTO.ПрочитатьJSON в Базе Б, могут возникнуть проблемы.

Даже если конфигурации идентичны, внутренние идентификаторы метаданных могут различаться, или, что более вероятно, объект просто отсутствует в целевой базе, и платформа не может сопоставить входящие данные (например, GUID ссылки) с реальным типом данных в текущей фабрике XDTO.

Решение:

Для обмена между разными базами рекомендуется использовать планы обмена или создавать собственные пакеты XDTO, которые будут идентичны в обеих базах. Если же вы просто тестируете механизм, убедитесь, что чтение происходит в той же базе, где была произведена запись, либо что объект метаданных полностью идентичен по структуре.

Причина 2: Конфликт имен реквизитов (Пользовательское поле "Ref")

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

В стандартном пакете XDTO поле ссылки часто обозначается как Ref. Когда сериализатор пытается разобрать ваш объект, он путает ваше пользовательское поле Ref (которое, например, является строкой) с системным полем ссылки (которое имеет сложный тип). Отсюда и возникает ошибка несоответствия типов Элемент vs string.

Решение:

Проверьте структуру метаданных вашего объекта. Никогда не называйте реквизиты зарезервированными именами:

Если такой реквизит найден, переименуйте его (например, в ВнешняяСсылка или RefID).

Причина 3: Явное и неявное указание типа при записи

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

Рассмотрим правильный пример записи объекта с явным указанием типа:


ИмяВременногоФайла = ПолучитьИмяВременногоФайла("json");
	
// Сериализация и запись объекта в файл JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(ИмяВременногоФайла);
	
// Важный момент: используем НазначениеТипаXML.Явное
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, СправочникОбъект, НазначениеТипаXML.Явное);
	
ЗаписьJSON.Закрыть();

Параметр НазначениеТипаXML.Явное заставляет платформу добавлять в JSON служебные поля (обычно #type), которые помогают при чтении однозначно определить, какой объект восстанавливать.

Теперь рассмотрим процедуру чтения. Если мы записали с явным типом, то чтение должно происходить корректно:


// Чтение и десериализация объекта из файла JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(ИмяВременногоФайла);
	
// Платформа считает тип из файла и попытается найти его в Глобальной Фабрике XDTO
Попытка
	СправочникОбъект = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
Исключение
	// Здесь мы перехватываем ошибку, если структура не совпала
	Сообщить("Ошибка чтения: " + ОписаниеОшибки());
КонецПопытки;
	
ЧтениеJSON.Закрыть();

Если вы не использовали явное указание типа при записи, файл JSON получается "чистым" (без служебных символов 1С), но при чтении СериализаторXDTO может не понять, в какой именно объект превращать прочитанные данные, особенно если структура файла неоднозначна.

Причина 4: "Битые" ссылки или пустые значения

Еще одна возможная причина ошибки Тип: string — это некорректная обработка пустых ссылок. Если в сериализуемом объекте есть реквизит ссылочного типа, который не заполнен (ПустаяСсылка), в JSON он может записаться как null или пустая строка, в то время как XDTO схема ожидает объектную структуру.

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


"MyReferenceField": ""

А схема ожидает:


"MyReferenceField": {
    "#type": "jcfg:CatalogRef.MyCatalog",
    "#value": "..."
}

То возникнет ошибка преобразования.

Комплексный алгоритм решения проблемы

Если вы столкнулись с ошибкой "НачалоСвойства: Ref", выполните следующие шаги для диагностики и исправления:

  1. Проверка контекста выполнения: Убедитесь, что чтение выполняется в той же конфигурации, что и запись. Если базы разные, убедитесь, что объект метаданных существует в приемнике и его структура идентична.
  2. Анализ имен реквизитов: Откройте конфигуратор и проверьте реквизиты объекта. Ищите реквизиты с именем Ref, Ссылка, Type. Переименуйте их.
  3. Валидация JSON файла: Откройте полученный файл в текстовом редакторе. Посмотрите, как записаны ссылки. Если файл создавался вручную или сторонней системой, он может не соответствовать формату, который ожидает 1С (IBM JSON vs 1C JSON).
  4. Использование явной типизации: Попробуйте перезаписать файл, используя параметр НазначениеТипаXML.Явное в методе ЗаписатьJSON.
  5. Явное указание типа при чтении: Если файл записан без типов, подскажите сериализатору, что вы ожидаете получить. Используйте второй параметр метода ПрочитатьJSON:

// Пример чтения с явным указанием ожидаемого типа
ТипОбъекта = Тип("СправочникОбъект.МойСправочник");
Данные = СериализаторXDTO.ПрочитатьJSON(Чтение, ТипОбъекта);

Этот подход часто помогает, когда платформа не может автоматически определить тип из входящей строки JSON.

Заключение

Ошибка "НачалоСвойства: Ref Форма: Элемент Тип: string" почти всегда указывает на рассинхронизацию между структурой данных в файле и схемой XDTO, которую использует платформа в данный момент. Чаще всего это происходит при переносе данных между разными базами или при наличии конфликтов имен в метаданных. Используйте приведенные выше методы проверки, и вы сможете успешно восстановить объект из JSON.

← На главную