Как правильно передать сложный параметр в сторонний веб-сервис и избежать ошибок XDTO?

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

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

Проанализируем ситуацию и типичные ошибки

Рассмотрим частый сценарий. Имеется веб-сервис, в котором есть метод SetGoods. Этот метод принимает параметр Request с типом Goods. Логичным на первый взгляд решением кажется формирование XML-строки с нужными данными и присвоение этой строки параметру веб-сервиса. Однако, при таком подходе код выдает ошибку:


WSПараметр.Request = ЗаписьХМЛ; // ЗаписьХМЛ - это сформированная строка
// Ошибка: Значение не может быть установлено свойству, имеющему объектный тип

Выясним причину этой ошибки. Дело в том, что свойство Request имеет объектный тип XDTO, и платформа 1С строго следит за соответствием типов. Мы не можем просто передать текстовую строку (даже если это валидный XML) в свойство, которое ожидает конкретный объект ОбъектXDTO с типом Goods из определенного пространства имен.

Разберем правильное создание объектов XDTO

Чтобы метод веб-сервиса отработал корректно, нам нужно использовать ФабрикаXDTO, которая автоматически создается в объекте WSПрокси, и конструировать объекты именно через нее. Посмотрим на пример, как правильно инициализировать типы и создавать объекты.


Определение = Новый WSОпределения(СокрЛП(Объект.АдресТест), СокрЛП(Объект.ЛогинТест), СокрЛП(Объект.ПарольТест));
Прокси = Новый WSПрокси(Определение, "IntegratedExchange", "IntegratedExchangeSoap");

// Получаем правильный тип из фабрики XDTO прокси
ТипОбъектаТовары = Прокси.ФабрикаXDTO.Тип("http://example.com/namespace", "Goods");
// Создаем корневой объект
Товары = Прокси.ФабрикаXDTO.Создать(ТипОбъектаТовары);

// Получаем тип для подчиненного элемента - конкретного товара
ТипОбъектаТовар = Прокси.ФабрикаXDTO.Тип("http://example.com/namespace", "GoodItem");
// Создаем объект товара
Товар = Прокси.ФабрикаXDTO.Создать(ТипОбъектаТовар);

// Заполняем свойства товара
Товар.ID = "34343";
Товар.Name = "Тестовый товар";

Как работать со списками XDTO

Если веб-сервис ожидает список товаров, то в XDTO схеме (WSDL) у параметра обычно указано свойство maxOccurs="unbounded". Платформа 1С в таком случае автоматически формирует для свойства тип СписокXDTO. Посмотрим, как добавлять элементы в этот список. Мы не можем просто присвоить значение, нам необходимо использовать метод Добавить().


// Добавляем созданный товар в коллекцию
Товары.Good.Добавить(Товар);

// Вызываем метод веб-сервиса и передаем сформированный XDTO объект
Ответ = Прокси.SetGoods(Товары);

Важные нюансы при работе с веб-сервисами и XDTO

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

  1. Пространства имен (Namespaces). При обращении к методу Прокси.ФабрикаXDTO.Тип("Namespace", "TypeName") критически важно указывать точное URI пространства имен. Часто оно выглядит как веб-адрес. Если передать неверный URI (или оставить строку пустой), фабрика XDTO вернет Неопределено, и метод Создать() упадет с ошибкой.
  2. Передача пустых параметров. Если в структуре XDTO есть необязательные поля (в WSDL указано nillable="true" или minOccurs="0"), и вы не хотите их заполнять, передавайте туда значение Неопределено. В этом случае 1С автоматически сформирует правильный XML-тег с атрибутом xsi:nil="true".
  3. Таймауты и безопасность. При использовании динамического прокси не забывайте указывать таймаут соединения. У объекта WSПрокси есть свойство Таймаут. Также, если сервис работает по HTTPS, в параметры конструктора WSОпределения рекомендуется передавать объект Новый ЗащищенноеСоединениеOpenSSL() для корректной работы с сертификатами.

Альтернативный подход: Статические WS-ссылки

Если структура веб-сервиса меняется редко, мы рекомендуем использовать статические WS-ссылки. Добавив WS-ссылку прямо в дерево метаданных конфигурации, вы получите ряд преимуществ:

Отладка сформированного XDTO-объекта

Часто бывает так, что вызов метода 1С проходит без ошибок, но сторонняя система возвращает отказ или сообщает о неверном формате данных. Разберем, как посмотреть "сырой" XML, который 1С отправляет на сервер. Для этого можно сериализовать наш подготовленный объект XDTO в строку:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Записываем наш объект "Товары" в формате XML
Прокси.ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, Товары);
СтрокаXML = ЗаписьXML.Закрыть();

Сообщить(СтрокаXML); // Теперь можно визуально проверить сформированный запрос

Этот простой метод позволит вам сравнить отправляемый 1С файл с эталонным XML-запросом (например, сформированным в SoapUI) и быстро найти недостающие поля или некорректно заполненные списки.

← На главную