При работе с механизмами сериализации в платформе 1С:Предприятие мы часто сталкиваемся с задачей сохранения объектов в формат JSON и их последующего чтения. Это стандартная процедура для обмена данными или сохранения состояния объектов. Однако, даже в простых случаях может возникнуть ошибка преобразования данных XDTO, текст которой выглядит следующим образом:
Ошибка преобразования данных XDTO: НачалоСвойства: Ref Форма: Элемент Тип: {http://www.w3.org/2001/XMLSchema}string
Давайте подробно разберем, почему возникает эта ошибка, что она означает с технической точки зрения и какие существуют способы ее устранения. Мы проанализируем ситуацию, начиная от проверки кода и заканчивая особенностями метаданных конфигурации.
Прежде чем переходить к решениям, давайте расшифруем сообщение системы. Сериализатор XDTO (XML Data Transfer Objects) работает на основе схем данных. В 1С любой ссылочный объект (Справочник, Документ) имеет стандартное описание в глобальной фабрике XDTO.
Ошибка сообщает нам о конфликте ожиданий и реальности:
Или наоборот, в зависимости от контекста: ожидалась строка (UUID), а пришел объект. Этот конфликт блокирует дальнейшее чтение данных.
В ходе анализа практических ситуаций (как это было выяснено в обсуждаемой теме) одной из самых частых причин является попытка прочитать сериализованный объект в базе, отличной от той, где он был записан.
Разберем эту ситуацию подробнее. Когда мы используем глобальный СериализаторXDTO, он опирается на метаданные текущей конфигурации. Если вы записали объект справочника в файл JSON в Базе А, а затем пытаетесь прочитать его через СериализаторXDTO.ПрочитатьJSON в Базе Б, могут возникнуть проблемы.
Даже если конфигурации идентичны, внутренние идентификаторы метаданных могут различаться, или, что более вероятно, объект просто отсутствует в целевой базе, и платформа не может сопоставить входящие данные (например, GUID ссылки) с реальным типом данных в текущей фабрике XDTO.
Решение:
Для обмена между разными базами рекомендуется использовать планы обмена или создавать собственные пакеты XDTO, которые будут идентичны в обеих базах. Если же вы просто тестируете механизм, убедитесь, что чтение происходит в той же базе, где была произведена запись, либо что объект метаданных полностью идентичен по структуре.
Это неочевидная, но критическая ошибка проектирования. Если вы добавили в свой справочник или документ реквизит с именем Ref (или Ссылка, если речь идет об английской транслитерации в схемах), это вызывает конфликт с системными полями XDTO.
В стандартном пакете XDTO поле ссылки часто обозначается как Ref. Когда сериализатор пытается разобрать ваш объект, он путает ваше пользовательское поле Ref (которое, например, является строкой) с системным полем ссылки (которое имеет сложный тип). Отсюда и возникает ошибка несоответствия типов Элемент vs string.
Решение:
Проверьте структуру метаданных вашего объекта. Никогда не называйте реквизиты зарезервированными именами:
RefTypeUUIDObjectЕсли такой реквизит найден, переименуйте его (например, в ВнешняяСсылка или RefID).
Давайте рассмотрим программный код. Ошибка может возникать из-за того, как именно мы записываем 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 может не понять, в какой именно объект превращать прочитанные данные, особенно если структура файла неоднозначна.
Еще одна возможная причина ошибки Тип: string — это некорректная обработка пустых ссылок. Если в сериализуемом объекте есть реквизит ссылочного типа, который не заполнен (ПустаяСсылка), в JSON он может записаться как null или пустая строка, в то время как XDTO схема ожидает объектную структуру.
Проанализируем содержимое вашего JSON файла. Если вы видите что-то подобное для ссылочных полей:
"MyReferenceField": ""
А схема ожидает:
"MyReferenceField": {
"#type": "jcfg:CatalogRef.MyCatalog",
"#value": "..."
}
То возникнет ошибка преобразования.
Если вы столкнулись с ошибкой "НачалоСвойства: Ref", выполните следующие шаги для диагностики и исправления:
Ref, Ссылка, Type. Переименуйте их.НазначениеТипаXML.Явное в методе ЗаписатьJSON.ПрочитатьJSON:
// Пример чтения с явным указанием ожидаемого типа
ТипОбъекта = Тип("СправочникОбъект.МойСправочник");
Данные = СериализаторXDTO.ПрочитатьJSON(Чтение, ТипОбъекта);
Этот подход часто помогает, когда платформа не может автоматически определить тип из входящей строки JSON.
Ошибка "НачалоСвойства: Ref Форма: Элемент Тип: string" почти всегда указывает на рассинхронизацию между структурой данных в файле и схемой XDTO, которую использует платформа в данный момент. Чаще всего это происходит при переносе данных между разными базами или при наличии конфликтов имен в метаданных. Используйте приведенные выше методы проверки, и вы сможете успешно восстановить объект из JSON.