Интеграция 1С со сторонними системами через веб-сервисы SOAP — частая прикладная задача. Однако при первых попытках вызвать методы удаленного сервиса разработчики нередко сталкиваются с исключением: «Несоответствие типов (параметр номер '1')». Разберем по шагам, почему возникает эта ошибка, как правильно формировать сложные типы XDTO для передачи параметров в SOAP-запросы, а также рассмотрим нюансы вывода полученных числовых значений в интерфейсе платформы.
Рассмотрим типовой сценарий. В информационной системе поднят SOAP-сервис (например, на платформе .NET/ASMX). Сначала вызывается метод авторизации Login, который принимает логин и пароль в виде простых строк и возвращает токен авторизации:
Прокси = WSСсылки.WSCсылка1.СоздатьWSПрокси("http://.../", "ImportStaff", "ImportStaffSoap");
Авторизация = Прокси.Login("Username", "Password");
Переменная Авторизация содержит строковое значение токена. Следующим шагом вызывается метод получения данных GetStaffTree, который согласно WSDL-описанию ожидает параметр авторизации. При прямой передаче полученной строки Данные = Прокси.GetStaffTree(Авторизация); платформа 1С прерывает выполнение с ошибкой:
Ошибка при вызове метода контекста (GetStaffTree)
по причине:
Несоответствие типов (параметр номер '1')
Проанализируем причину сбоя. В схеме WSDL параметр метода объявлен не как скалярная строка (string), а как составной тип данных — например, authHeader, содержащий внутри дочерний элемент AuthenticatedToken. Метод GetStaffTree ожидает на вход полноценный ОбъектXDTO заданной структуры, а не примитивную строку платформы 1С. Платформа строго проверяет соответствие сигнатур, поэтому возникает ошибка приведения типов.
Чтобы метод принял параметр, необходимо программно создать экземпляр требуемого типа с помощью фабрики XDTO, доступной через созданный прокси-объект. Разберем правильную последовательность действий:
Прокси.ФабрикаXDTO.Фабрика.Тип(URIПространстваИмен, ИмяТипа).Фабрика.Создать(...).Посмотрим на рабочий пример реализации:
// 1. Инициализируем прокси для веб-сервиса
URIПространства = "http://.../";
Прокси = WSСсылки.WSCсылка1.СоздатьWSПрокси(URIПространства, "ImportStaff", "ImportStaffSoap");
Фабрика = Прокси.ФабрикаXDTO;
// 2. Получаем строковый токен авторизации
ТокенАвторизации = Прокси.Login("Username", "Password");
// 3. Создаем объект составного типа AuthHeader
ТипAuthHeader = Фабрика.Тип(URIПространства, "AuthHeader");
ОбъектЗаголовка = Фабрика.Создать(ТипAuthHeader);
// 4. Заполняем поле токена
ОбъектЗаголовка.AuthenticatedToken = ТокенАвторизации;
// 5. Вызываем рабочий метод с передачей XDTO-объекта
ДанныеШтатногоРасписания = Прокси.GetStaffTree(ОбъектЗаголовка);
После выполнения этого кода платформа успешно сериализует ОбъектЗаголовка в соответствующий XML-элемент внутри soap:Body, и веб-сервис возвращает ответ без ошибок валидации схемы.
Использование статической WSСсылки из дерева метаданных удобно, но имеет существенный минус: при изменении схемы WSDL на стороне внешнего сервера 1С не увидит обновлений до тех пор, пока разработчик вручную не перечитает схему в конфигураторе. Если сервис часто обновляется, надежнее использовать динамическую инициализацию через WSОпределения:
URL_WSDL = "http://server/ImportStaff.asmx?WSDL";
Определения = Новый WSОпределения(URL_WSDL, "ЛогинHTTP", "ПарольHTTP", 30);
Прокси = Новый WSПрокси(Определения, "http://.../", "ImportStaff", "ImportStaffSoap");
Фабрика = Прокси.ФабрикаXDTO;
В этом случае платформа считывает актуальные типы и методы удаленной службы непосредственно в момент подключения к сервису.
Когда сервис возвращает сложные структуры данных (например, списки объектов StaffTree), важно учитывать правила работы платформы с массивами и скалярными типами:
ArrayOfStaffTree), в 1С она представляется типом СписокXDTO. Обход выполняется стандартным циклом Для Каждого. Однако, если возвращается ровно один элемент, при определенных настройках WSDL свойство может быть прочитано как одиночный ОбъектXDTO. При получении коллекций полезно проверять тип свойства: ТипЗнч(Результат.StaffTree) = Тип("СписокXDTO").short (Int16) и int (Int32). При выгрузке данных в 1С эти поля автоматически преобразуются в стандартный тип Число.Рассмотрим пример обхода и выгрузки возвращенной структуры в таблицу:
Для Каждого Элемент Из ДанныеШтатногоРасписания.StaffTree Цикл
НоваяСтрока = ШтатнаяСтруктура.Добавить();
НоваяСтрока.Код = Элемент.Code;
НоваяСтрока.Название = Элемент.Name;
НоваяСтрока.НазваниеКоротко = Элемент.ShortName;
НоваяСтрока.Тип = Элемент.IsDirectory;
НоваяСтрока.КодРодителя = Элемент.ParentCode;
НоваяСтрока.НазваниеРодителя = Элемент.ParentName;
НоваяСтрока.НазваниеРодителяКоротко = Элемент.ParentShortName;
КонецЦикла;
При переносе числовых данных из XDTO в колонку таблицы часто возникает визуальный дефект: положительные числа отображаются корректно, а значение 0 отображается как пустая ячейка. Например, если поле IsDirectory может принимать значения 0 (должность), 1 (подразделение) или 2 (вид должности), нули визуально пропадают.
Выясним причину: в платформе 1С для числовых полей ввода и колонок таблиц по умолчанию включено свойство скрытия нуля при отображении. Чтобы число 0 отображалось в интерфейсе, необходимо настроить формат вывода:
ЧН=0 (представление нуля). Например: ЧГ=0; ЧН=0.После настройки формата все числовые статусы и коды будут отображаться на форме корректно.