При разработке SOAP веб-сервисов в платформе 1С разработчики часто сталкиваются с ошибкой сериализации данных:
Ошибка SOAP сервера: Неизвестная ошибка. Ошибка отображения типов: Отображение типа 'Массив' в тип '{http://www.w3.org/2001/XMLSchema}string'
Разберем по шагам, почему возникает эта ошибка, где кроется типичная невнимательность разработчика и какими способами можно корректно передавать и возвращать списки значений через веб-сервисы.
Проанализируем механизм работы веб-сервисов (SOAP) в 1С. SOAP-сервисы жестко типизированы и опираются на схемы XDTO (XML Schema Definition). Когда для операции или параметра веб-сервиса в конфигураторе задан тип {http://www.w3.org/2001/XMLSchema}string, платформа ожидает скалярное строковое значение.
Встроенный тип 1С Массив является внутренней коллекцией значений и не имеет прямого автоматического сопоставления со стандартным типом string. Ошибка возникает в двух случаях:
string, но в коде функции модуля веб-сервиса с помощью оператора Возврат передается объект типа Массив (или промежуточная переменная коллекции).string, а вызывающая сторона отправляет структуру или массив объектов.Если ошибка вызвана опечаткой в коде функции веб-сервиса, достаточно проверить оператор Возврат и убедиться, что возвращается именно строковое значение, а не созданный для внутренних расчетов массив.
Рассмотрим наиболее популярный и простой способ передачи списков значений без изменения схемы типов веб-сервиса. Тип параметра или возвращаемого значения в конфигураторе остается string, а данные упаковываются в строку.
Посмотрим на пример упаковки массива в строку JSON на стороне веб-сервиса:
Функция ПолучитьСписокДанных()
МассивДанных = Новый Массив;
МассивДанных.Добавить("Элемент 1");
МассивДанных.Добавить("Элемент 2");
// Сериализуем массив в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивДанных);
СтрокаРезультат = ЗаписьJSON.Закрыть();
Возврат СтрокаРезультат;
КонецФункции
Теперь разберем, как прочитать полученную строку с разделителями или JSON-строку на стороне клиента:
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПолученнаяСтрока);
МассивРезультат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Для взаимодействия исключительно между двумя базами 1С можно использовать функции ЗначениеВXMLСтроку() и ЗначениеИзXMLСтроки().
Если веб-сервис должен соответствовать строгому контракту WSDL, где массивы передаются в виде структурированных XML-элементов, выполним настройку через пакет XDTO.
ArrayOfString.Item) со строковым типом string.-1 (что эквивалентно unbounded в XML Schema).Посмотрим, как сформировать и вернуть такой объект в модуле веб-сервиса:
Функция ПолучитьМассивXDTO()
ТипXDTO = ФабрикаXDTO.Тип("http://v8.1c.ru/custom-ws", "ArrayOfString");
ОбъектXDTO = ФабрикаXDTO.Создать(ТипXDTO);
МассивСтрок = Новый Массив;
МассивСтрок.Добавить("Значение 1");
МассивСтрок.Добавить("Значение 2");
Для Каждого Стр Из МассивСтрок Цикл
ОбъектXDTO.Item.Добавить(Стр);
КонецЦикла;
Возврат ОбъектXDTO;
КонецФункции
Если проект допускает архитектурные изменения, для передачи произвольных структур данных и массивов рекомендуется использовать объект конфигурации HTTP-сервисы вместо SOAP веб-сервисов.
HTTP-сервисы не требуют строгой XDTO-схемы, работают напрямую с телом запроса и ответа через объекты HTTPСервисЗапрос и HTTPСервисОтвет, что исключает ошибки несовместимости типов платформы и упрощает интеграцию с внешними системами.