Как передать массив или таблицу значений через веб-сервис 1С

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

При разработке интеграций на платформе 1С:Предприятие программисты часто сталкиваются с необходимостью передать через веб-сервис не просто строку или число, а сложные структуры данных, такие как Массив или ТаблицаЗначений. Стандартная попытка указать тип Array из пространства имен http://v8.1c.ru/8.1/data/core в определении веб-сервиса часто приводит к ошибке «Несоответствие типов» при вызове метода. Разберем подробно, почему это происходит и как правильно передавать такие данные.

Причина возникновения ошибки «Несоответствие типов»

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

Для решения этой задачи мы рассмотрим наиболее эффективный способ — использование механизма XDTO-сериализации.

Способ 1: Использование СериализаторXDTO и типа anyType

Самый простой и надежный способ передать массив между двумя базами 1С — это явное преобразование массива в объект XDTO перед отправкой. Для этого используется встроенный объект СериализаторXDTO. Проанализируем шаги реализации.

1. Настройка веб-сервиса

В дереве конфигурации найдем наш веб-сервис и операцию. Для параметра, который должен принимать массив, установим тип anyType (пространство имен http://www.w3.org/2001/XMLSchema). Это позволит передать объект любого типа, который 1С сможет сериализовать самостоятельно.

2. Подготовка данных на стороне клиента (отправителя)

В процедуре вызова веб-сервиса нам необходимо преобразовать программный объект Массив в формат, понятный фабрике XDTO. Рассмотрим пример кода:


&НаСервере
Процедура ВыполнитьВызовВебСервиса()
    // Создаем исходный массив данных
    МассивДанных = Новый Массив;
    МассивДанных.Добавить("Значение 1");
    МассивДанных.Добавить(100);
    МассивДанных.Добавить(ТекущаяДата());

    // Настраиваем соединение
    Определение = Новый WSОпределения("http://server/base/ws/test?wsdl", "Логин", "Пароль");
    Прокси = Новый WSПрокси(Определение, "http://www.my-ws-namespace.org", "My_Test_ws", "My_Test_wsSoap");
    
    // Ключевой момент: используем СериализаторXDTO для преобразования
    ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(МассивДанных);
    
    // Вызываем метод сервиса, передавая объект XDTO вместо обычного массива
    Результат = Прокси.ReturnDocs(ОбъектXDTO);
КонецПроцедуры

3. Обработка данных на стороне веб-сервиса (получателя)

Внутри функции самого веб-сервиса нам нужно выполнить обратное преобразование. Если параметр в определении указан как anyType, то в коде 1С он придет уже в виде готового объекта. Однако, если требуется восстановить именно тип Массив, мы используем метод ПрочитатьXDTO.


Функция ReturnDocs(ВходнойПараметр)
    // Преобразуем полученный XDTO обратно в массив 1С
    Массив = СериализаторXDTO.ПрочитатьXDTO(ВходнойПараметр);
    
    // Теперь с объектом "Массив" можно работать как обычно
    Для Каждого Элемент Из Массив Цикл
        // Обработка элементов
    КонецЦикла;
    
    Возврат "Данные получены";
КонецФункции

Передача таблицы значений

Передача ТаблицаЗначений технически мало чем отличается от передачи массива, но имеет свои нюансы. Напрямую сериализовать таблицу значений можно через тот же СериализаторXDTO, однако это создаст очень громоздкий XML-пакет, содержащий описание колонок, типов данных и индексов. Это может существенно замедлить работу при больших объемах данных.

Разберем более оптимальный алгоритм передачи таблицы:

  1. Преобразуем ТаблицаЗначений в Массив Структур. Каждая структура будет представлять собой строку таблицы, где ключ — имя колонки.
  2. Сериализуем этот массив с помощью СериализаторXDTO.ЗаписатьXDTO().
  3. Передаем в веб-сервис.

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

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


Функция ПреобразоватьТЗвМассив(ТаблицаДанных)
    МассивРезультат = Новый Массив;
    Для Каждого СтрокаТЗ Из ТаблицаДанных Цикл
        СтруктураСтроки = Новый Структура;
        Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
            СтруктураСтроки.Вставить(Колонка.Имя, СтрокаТЗ[Колонка.Имя]);
        КонецЦикла;
        МассивРезультат.Добавить(СтруктураСтроки);
    КонецЦикла;
    Возврат МассивРезультат;
КонецФункции

Альтернативный подход: Использование JSON

Проанализируем современный подход, который часто используется в высоконагруженных системах. Вместо того чтобы полагаться на сложные механизмы XDTO и anyType, данные можно передавать в виде обычной строки в формате JSON.

Преимущества этого метода:

Рассмотрим, как реализовать передачу массива через JSON:


// Код на стороне отправителя
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МойМассивИлиТЗ);
СтрокаДляПередачи = ЗаписьJSON.Закрыть();

// Передаем СтрокаДляПередачи в веб-сервис (тип параметра в WSDL - string)
Результат = Прокси.ИмяМетода(СтрокаДляПередачи);

// Код на стороне получателя (внутри веб-сервиса)
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ВходнаяСтрока);
Данные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Важные рекомендации при работе с XDTO

Рассмотрим несколько критических моментов, которые помогут избежать ошибок в будущем:

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

2. Использование собственных XDTO-пакетов. Если к вашему веб-сервису обращается не другая 1С, а внешняя система, использование anyType крайне не рекомендуется. В этом случае следует создать в конфигурации свой XDTO-пакет, описать в нем структуру объекта (например, "СписокТоваров", содержащий элементы "Товар") и использовать этот тип в веб-сервисе. Это создаст четкую структуру в WSDL-файле, которую внешние разработчики смогут легко импортировать в свои проекты.

3. Большие объемы данных. Помним, что веб-сервисы работают по протоколу HTTP и имеют ограничения на размер передаваемого XML. Если массив содержит десятки тысяч строк, рекомендуется сжимать его в ZIP-архив, переводить в Base64 и передавать как строку, либо организовать порционную (постраничную) передачу данных.

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

← На главную