Как исправить ошибку «Несоответствие типов XDTO: Тип не найден» при работе с веб-сервисами в 1С?

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

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

Суть проблемы и анализ исходного кода

Рассмотрим ситуацию на конкретном примере. Предположим, мы пытаемся передать структуру параметров документа во внешний веб-сервис со следующим кодом:


УникальныйИдентификаторШаблона = Новый УникальныйИдентификатор("22722772-d2da-11e8-80e7-005056b836bc");

// Записываем параметры документа.
ПараметрыДокумента = Новый Структура();
ПараметрыДокумента.Вставить("Заголовок", БП.ЗапросДок);
ПараметрыДокумента.Вставить("Содержание", Обоснование);
ПараметрыДокумента.Вставить("Комментарий", "Добавлено автоматически из IDM");
ПараметрыДокумента.Вставить("ШаблонДокумента", УникальныйИдентификаторШаблона);

// ОТПРАВКА ДАННЫХ В WEB-СЕРВИС И ПОЛУЧЕНИЕ ОТВЕТА
ПараметрыДокументаXDTO = СериализаторXDTO.ЗаписатьXDTO(ПараметрыДокумента);
РезультатВыполненияXDTO = Прокси.AddInternalDocument(ПараметрыДокументаXDTO);

При выполнении последней строки система генерирует критическую ошибку:

«Несоответствие типов XDTO: Тип '{http://v8.1c.ru/8.1/data/enterprise/current-config}DocumentRef.ЗапросПрав' не найден. Тип принадлежит пакету, отсутствующему в фабрике типов XDTO».

Давайте разберем по шагам, почему это происходит. Пространство имен current-config (полный URI: http://v8.1c.ru/8.1/data/enterprise/current-config) — это динамический пакет XDTO, который платформа 1С автоматически создает «на лету» для описания метаданных текущей информационной базы (справочников, документов, перечислений и т. д.). Когда мы вызываем глобальный метод СериализаторXDTO.ЗаписатьXDTO(ПараметрыДокумента), платформа задействует системную глобальную фабрику XDTO. Поскольку в свойство Заголовок передана прямая ссылка на документ (ДокументСсылка.ЗапросПрав), глобальный сериализатор преобразует эту ссылку в сложный объект XDTO, принадлежащий пространству имен current-config.

Однако, когда мы передаем полученный объект ПараметрыДокументаXDTO в метод Прокси.AddInternalDocument(), платформа использует фабрику XDTO самого веб-сервиса (сформированную на основе импортированного WSDL-описания). Эта фабрика ничего не знает о метаданных нашей конкретной базы 1С — пакет current-config в ней отсутствует. В результате сопоставления типов происходит сбой, и платформа выбрасывает исключение.

Почему интеграция работала раньше?

Часто разработчики утверждают, что интеграция долгое время функционировала корректно без каких-либо изменений в коде. Проанализируем возможные причины внезапного появления этой проблемы:

  1. Изменение типа передаваемых данных. Это наиболее частая причина. Раньше в свойство Заголовок (или аналогичное ему) записывалось простое текстовое значение (например, строка с наименованием или номером документа). Простые типы данных (такие как строка, число, дата) сериализуются в стандартные типы XML Schema (пространство имен http://www.w3.org/2001/XMLSchema), которые по умолчанию поддерживаются любой фабрикой XDTO. Как только тип реквизита изменился на ссылку (DocumentRef), сериализатор попытался передать сложный объект 1С.
  2. Обновление платформы 1С. В разных релизах платформы поведение глобального сериализатора по умолчанию при обработке универсальных коллекций (таких как Структура или Соответствие) может несколько различаться, особенно при передаче их в параметры с типом anyType.
  3. Изменение структуры веб-сервиса. На принимающей стороне могли измениться типы принимаемых аргументов или схемы валидации данных в WSDL, из-за чего контроль типов стал более строгим.

Способы решения проблемы

Существует три основных подхода к устранению данной ошибки, в зависимости от архитектурных требований вашей системы.

Вариант А. Использование сериализатора из WS-прокси (Быстрое исправление)

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


// Заменяем глобальный сериализатор на сериализатор конкретного WS-прокси
ПараметрыДокументаXDTO = Прокси.СериализаторXDTO.ЗаписатьXDTO(ПараметрыДокумента);
РезультатВыполненияXDTO = Прокси.AddInternalDocument(ПараметрыДокументаXDTO);

Этот способ быстро решает проблему, но только при условии, что импортированная в конфигурацию WS-ссылка действительно содержит описание схемы current-config.

Вариант Б. Передача простых типов (Рекомендуемый архитектурный подход)

С точки зрения правильного проектирования интеграционных решений, внешние веб-сервисы не должны зависеть от внутренних типов и метаданных конфигурации 1С. Передача прямых ссылок (DocumentRef, CatalogRef) между независимыми системами считается плохой практикой.

Мы рекомендуем передавать уникальные идентификаторы документов в виде обычных строковых значений. Если на принимающей стороне также развернута база 1С, она сможет легко найти или создать документ по полученному строковому представлению UUID. Модифицируем наш исходный код следующим образом:


УникальныйИдентификаторШаблона = Новый УникальныйИдентификатор("22722772-d2da-11e8-80e7-005056b836bc");

ПараметрыДокумента = Новый Структура();
// Вместо прямой ссылки 1С передаем строковое представление GUID
ПараметрыДокумента.Вставить("Заголовок", Строка(БП.ЗапросДок.УникальныйИдентификатор()));
ПараметрыДокумента.Вставить("Содержание", Обоснование);
ПараметрыДокумента.Вставить("Комментарий", "Добавлено автоматически из IDM");
ПараметрыДокумента.Вставить("ШаблонДокумента", Строка(УникальныйИдентификаторШаблона));

// Теперь сериализация пройдет успешно, так как структура содержит только базовые типы (строки)
ПараметрыДокументаXDTO = СериализаторXDTO.ЗаписатьXDTO(ПараметрыДокумента);
РезультатВыполненияXDTO = Прокси.AddInternalDocument(ПараметрыДокументаXDTO);

Использование строк вместо сложных объектов 1С полностью исключает возникновение ошибок пространства имен current-config и делает интеграцию максимально надежной и гибкой к изменениям метаданных в любой из баз.

Вариант В. Добавление пакета XDTO на стороне веб-сервиса 1С

Если веб-сервис разработан вами в другой информационной базе 1С и вы имеете к нему доступ для редактирования, можно явно разрешить использование типов текущей конфигурации. Для этого выполните следующие шаги в конфигураторе базы, где опубликован веб-сервис:

  1. Откройте свойства вашего Web-сервиса в дереве метаданных.
  2. Найдите свойство «Пакеты XDTO».
  3. В открывшемся списке установите флажок напротив пакета с URI http://v8.1c.ru/8.1/data/enterprise/current-config.
  4. Сохраните изменения и обновите публикацию веб-сервиса на веб-сервере (IIS или Apache).
  5. В вызывающей базе обязательно обновите WS-ссылку, чтобы клиентская фабрика получила актуальное описание типов.

Важное предупреждение: Помните, что использование динамического пакета current-config в межбазовом обмене имеет серьезный недостаток. Если одна из конфигураций обновится (например, добавятся или удалятся реквизиты документа ЗапросПрав), структура пакета изменится, что снова приведет к ошибкам десериализации данных. Поэтому для долгосрочных интеграционных проектов всегда правильнее создавать собственные статические XDTO-пакеты с фиксированной структурой данных, состоящей из простых типов.

← На главную