Как исправить проблему десериализации системных объектов 1С (например, ТаблицыЗначений) в Web-сервисах?

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

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

В этой статье мы подробно разберем, почему возникает такая ошибка, проанализируем механизм работы фабрики XDTO в контексте веб-сервисов и выясним, какие настройки в метаданных необходимо выполнить для правильной десериализации «родных» объектов 1С.

Суть проблемы: почему объект превращается в anyType?

Рассмотрим ситуацию: одна база 1С формирует XML-пакет с помощью СериализатораXDTO. В этом пакете содержится, например, ТаблицаЗначений. В XML это выглядит как элемент с атрибутом i:type="v83:ValueTable", где префикс v83 ссылается на пространство имен http://v8.1c.ru/8.1/data/core.

Когда этот XML попадает в Web-сервис другой базы, платформа 1С пытается сопоставить описание типа из XML со списком доступных ей типов в ФабрикеXDTO. Если в конфигурации Web-сервиса явно не указано, что он должен уметь работать с системными типами 1С, платформа «теряется». Не найдя определения для ValueTable в своих локальных схемах, она классифицирует узел как максимально абстрактный — anyType (из пространства имен http://www.w3.org/2001/XMLSchema). В итоге, попытка преобразовать такой объект обратно в ТаблицуЗначений программно заканчивается неудачей.

Решение проблемы: настройка пакетов XDTO в метаданных

Основная причина кроется в настройках самого объекта Web-сервис в дереве метаданных. Разберем по шагам, как это исправить:

  1. Откроем конфигуратор и найдем нужный нам Web-сервис.
  2. Перейдем в палитру свойств этого сервиса.
  3. Найдем свойство Пакеты XDTO.
  4. Нажмем на кнопку выбора (три точки) и добавим в список стандартный пакет 1С: http://v8.1c.ru/8.1/data/core.

Важный нюанс: в зависимости от версии платформы и используемых типов, вам также могут понадобиться пакеты http://v8.1c.ru/8.1/data/enterprise/current-config (для ссылочных типов конфигурации) или другие системные пространства имен. После добавления пакета http://v8.1c.ru/8.1/data/core платформа начнет узнавать тип ValueTable, и автоматическая десериализация заработает корректно.

Различие между ФабрикойXDTO и СериализаторомXDTO

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

ФабрикаXDTO — это низкоуровневый механизм. Она читает XML и создает ОбъектXDTO. Этот объект не является ТаблицейЗначений в терминах 1С, это лишь иерархическая структура данных, «отражение» XML. Если фабрика не знает о существовании пространства имен .../data/core, она создаст объект типа anyType.

СериализаторXDTO — это «обертка» над фабрикой, которая умеет превращать ОбъектXDTO в прикладной объект 1С (и наоборот). Рассмотрим пример кода, который правильно восстанавливает таблицу из объекта XDTO в модуле веб-сервиса:


// Предположим, ДанныеXDTO - это параметр метода веб-сервиса
// Если пакеты XDTO подключены верно, тип объекта будет правильным

Если ТипЗнч(ДанныеXDTO) = Тип("ОбъектXDTO") Тогда
    
    // Пытаемся восстановить прикладной объект (ТаблицуЗначений)
    Попытка
        МояТаблица = СериализаторXDTO.ПрочитатьXDTO(ДанныеXDTO);
        
        // Теперь с переменной МояТаблица можно работать как с обычной ТЗ
        Для Каждого СтрокаТЗ Из МояТаблица Цикл
            // Обработка данных
        КонецЦикла;
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка десериализации", 
            УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
    КонецПопытки;
    
КонецЕсли;

Проблема версий пространств имен (v81, v82, v83)

Проанализируем ситуацию, когда базы работают на разных версиях платформы. Пространство имен http://v8.1c.ru/8.1/data/core является стандартным, но префиксы (например, v83 или v82) в самом тексте XML могут различаться.

Выясним причину возможных сбоев: если отправитель жестко прописывает URI пространства имен, который не совпадает с тем, что ожидает приемник (например, из-за различий в режиме совместимости), десериализация может не сработать даже при подключенном пакете. Всегда проверяйте атрибут xmlns в передаваемом XML. Он должен в точности соответствовать URI пакета, указанного в свойствах веб-сервиса.

Нюансы передачи метаданных колонок

Даже если сама ТаблицаЗначений распознана успешно, данные внутри нее могут оказаться некорректными. Разберем, почему это происходит:

Альтернативный подход: передача через строку XML

Рассмотрим ситуацию, когда стандартная передача через параметры XDTO становится слишком громоздкой. XML-описание ТаблицыЗначений очень избыточно: на каждую ячейку создается несколько тегов с описанием типов. Если таблица большая (тысячи строк), объем трафика растет в геометрической прогрессии.

Опытные разработчики часто используют «обходной маневр»: на стороне отправителя таблица принудительно сериализуется в строку, а на стороне веб-сервиса эта строка принимается как обычный текст и десериализуется вручную.

Пример кода на стороне отправителя:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТаблицаДляПередачи);
СтрокаXML = ЗаписьXML.Закрыть();
// Далее передаем СтрокаXML как параметр типа string в веб-сервис

Пример кода на стороне получателя (внутри метода Web-сервиса):


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ВходящаяСтрокаXML);
// Здесь важно использовать СериализаторXDTO напрямую
МояТаблица = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);

Этот метод избавляет от необходимости жесткой привязки пакетов XDTO к метаданным веб-сервиса в некоторых случаях, так как СериализаторXDTO.ПрочитатьXML использует глобальный контекст типов платформы, а не ограниченный набор пакетов конкретного Web-сервиса.

Влияние режима совместимости

В завершение проанализируем влияние режима совместимости конфигурации. При изменении версии платформы (например, переход с 8.3.10 на 8.3.20) состав стандартных пакетов, доступных «по умолчанию» без явного указания, может меняться. Если ваша интеграция внезапно перестала работать после обновления платформы, первым делом проверьте список подключенных пакетов XDTO в свойствах веб-сервиса. Явное указание необходимых пакетов (v8:core) — это залог стабильной работы распределенных систем.

Таким образом, мы выяснили, что для успешной передачи системных объектов 1С через Web-сервисы необходимо не только правильно использовать СериализаторXDTO, но и корректно декларировать используемые типы данных в метаданных конфигурации.

← На главную