Как передать составной параметр или массив в веб-сервис в 1С 8.3

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

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

Разберем по шагам, как правильно подготовить и передать составной объект и массив данных в SOAP веб-сервис как при использовании статической ссылки (объекта конфигурации WS-ссылки), так и при динамическом подключении через WSОпределения.

Способ 1. Передача составного объекта (структуры) через статическую WS-ссылку

Проанализируем ситуацию, когда WSDL-схема уже импортирована в дерево метаданных конфигурации в ветку WS-ссылки. В этом случае фабрика XDTO доступна напрямую из объекта WSПрокси.

Выясним последовательность действий для передачи составного типа:

  1. Инициализируем прокси сервиса с помощью метода СоздатьWSПрокси.
  2. Обращаемся к фабрике XDTO через свойство ФабрикаXDTO нашего прокси-объекта.
  3. Получаем тип XDTO с помощью метода ФабрикаXDTO.Тип(), передав URI пространства имен схемы и имя сложного типа.
  4. Создаем экземпляр типа с помощью метода ФабрикаXDTO.Создать().
  5. Заполняем свойства созданного ОбъектXDTO значениями и передаем его в метод сервиса.

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


// Инициализируем объект-посредник
НашСервис = WSСсылки.Портал.СоздатьWSПрокси("URI_ПространстваИменСервиса", "ИмяСервиса", "ИмяТочкиПодключения");

// Получаем фабрику XDTO сервиса
Фабрика = НашСервис.ФабрикаXDTO;

// Получаем тип составного параметра по пространству имен XSD-схемы и имени типа
ТипПараметра = Фабрика.Тип("http://external-system.org/types", "CustomerData");

// Создаем экземпляр сложного типа
СоставнойПараметр = Фабрика.Создать(ТипПараметра);

// Заполняем поля объекта
СоставнойПараметр.Поле1 = ЗначениеПоля1;
СоставнойПараметр.Поле2 = ЗначениеПоля2;
СоставнойПараметр.Поле3 = ЗначениеПоля3;

// Вызываем метод веб-сервиса
Результат = НашСервис.RegisterCustomer(СоставнойПараметр);

Способ 2. Динамическое подключение и отправка сложного объекта

Рассмотрим подробнее вариант, когда WSDL-файл загружается динамически по сетевому адресу (URL) без сохранения в метаданных конфигурации 1С. В этом случае фабрику типов предоставляет объект WSОпределения.

Посмотрим на пример реализации динамического вызова:


АдресWSDL = "http://api.service.com/service.wsdl";
Определение = Новый WSОпределения(АдресWSDL, ЛогинWS, ПарольWS);

ПространствоИменСервиса = "http://api.service.com/ws";
ИмяСервиса = "MainService";
ИмяТочкиПодключения = "MainServiceSoapPort";

Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
Фабрика = Определение.ФабрикаXDTO;

// Создаем объект требуемого типа
ТипОбъекта = Фабрика.Тип(ПространствоИменСервиса, "TestClass41");
ОбъектСервиса = Фабрика.Создать(ТипОбъекта);

ОбъектСервиса.a = Параметр41;
ОбъектСервиса.b = Параметр42;
ОбъектСервиса.res = 0;

// Выполняем вызов метода веб-сервиса
ОбъектРезультат = Прокси.test4(ОбъектСервиса);
Результат = ОбъектРезультат.res;

Способ 3. Передача массива (коллекции элементов) в метод сервиса

Часто в методах веб-сервисов требуется передать не просто один объект, а список однотипных записей (в XSD-схеме такое свойство описывается атрибутом maxOccurs="unbounded"). В объектной модели 1С такие поля представляются типом СписокXDTO.

Важное правило: прямое присвоение массива 1С (например, ОбъектСервиса.arr = Массив1С) вызовет ошибку несоответствия типов. Наполнение списка выполняется строго с помощью метода Добавить() у свойства-коллекции родительского объекта XDTO.

Разберем по шагам заполнение составного массива:

  1. Создаем родительский объект XDTO, содержащий свойство-список.
  2. Обходим исходную коллекцию данных 1С (таблицу значений, массив структур и т.д.) в цикле.
  3. На каждой итерации создаем экземпляр элементарного объекта XDTO нужного типа.
  4. Заполняем свойства элемента и добавляем его в список родительского объекта через Родитель.Список.Добавить(Элемент).
  5. Передаем сформированный родительский объект в метод веб-сервиса.

Посмотрим на пример кода заполнения массива и обработки полученного ответа:


Определение = Новый WSОпределения(АдресWSDL);
Прокси = Новый WSПрокси(Определение, ПространствоИменСервиса, ИмяСервиса, ИмяТочкиПодключения);
Фабрика = Определение.ФабрикаXDTO;

// Создаем корневой составной объект
ОбъектСервиса = Фабрика.Создать(Фабрика.Тип(ПространствоИменСервиса, "TestClass51"));

// Получаем тип вложенных элементов массива
ТипЭлементаСписка = Фабрика.Тип(ПространствоИменСервиса, "TestClass52");

// Наполняем свойство arr элементами
Для Каждого Стр Из ТаблицаПараметров Цикл
    Элемент = Фабрика.Создать(ТипЭлементаСписка);
    ЗаполнитьЗначенияСвойств(Элемент, Стр);
    ОбъектСервиса.arr.Добавить(Элемент);
КонецЦикла;

// Вызов веб-сервиса
ОбъектРезультат = Прокси.test5(ОбъектСервиса);

// Чтение массива из ответа сервиса
Результат = Новый Массив;
Для Каждого ЭлементРезультата Из ОбъектРезультат.res Цикл
    Результат.Добавить(ЭлементРезультата);
КонецЦикла;

Тонкости и типичные ошибки при работе со схемами XDTO

Проанализируем ключевые нюансы, которые необходимо учитывать при передаче параметров через XDTO:

  1. Разделение пространств имен. Пространство имен самого сервиса (целевое пространство WSDL) и пространство имен типов данных XSD-схемы часто отличаются. При получении типа через Фабрика.Тип(URI, ИмяТипа) необходимо указывать точный URI схемы, где объявлен конкретный тип.
  2. Порядок следования полей. Если в XSD-схеме используется блок xs:sequence, порядок инициализации свойств объекта XDTO должен строго соответствовать порядку, объявленному в схеме. Нарушение последовательности может приводить к ошибкам валидации XML на стороне сервера.
  3. Неинициализированные и пустые поля. Если свойство в схеме не помечено признаком nillable="true", передача значения Неопределено вызовет исключение. Если свойство опционально (minOccurs="0"), для корректной сериализации его лучше не трогать вовсе, чтобы не генерировать пустые некорректные XML-узлы.
← На главную