При интеграции с внешними системами, такими как банковские веб-сервисы, мы часто сталкиваемся с необходимостью подключения по WSDL-файлу, предоставленному контрагентом. В идеальном мире банк предоставил бы ссылку на веб-сервис, и мы могли бы легко добавить её в 1С. Однако, как показывает практика, нередко нам присылают локальные файлы .wsdl и .xsd, а попытка подключиться к веб-сервису 1С по такому локальному файлу через конструкцию Новый WSОпределения("file://C:/путь/к/файлу.wsdl") выдаёт ошибку "Неверный формат" или другие неочевидные сообщения. Рассмотрим эту проблему подробнее и выясним, как её решить.
Главная трудность возникает из-за двух основных факторов:
WS-Policy, WS-Addressing, WS-Security в версиях 8.3.7 и ниже, или некорректные пространства имён).Новый WSОпределения("file://C:/..."), мы обычно запускаем его на сервере (например, в серверной процедуре &НаСервере). Однако путь C:/... относится к локальной файловой системе клиентской машины, а не сервера. Сервер 1С не имеет доступа к файлам, расположенным на локальном диске пользователя. Это приводит к тому, что сервер просто не может найти и прочитать указанный файл, даже если он совершенно корректен.Именно проблема клиент-серверного взаимодействия часто является камнем преткновения, приводящим к ошибкам вида "Неверный формат" или "Элемент не найден", так как система пытается парсить несуществующий или некорректно прочитанный файл.
Прежде чем погружаться в более сложные решения, давайте убедимся, что наши файлы .wsdl и .xsd максимально корректны и, по возможности, попробуем использовать встроенные механизмы 1С.
Поскольку 1С не имеет встроенного валидатора WSDL, мы рекомендуем использовать сторонние инструменты для проверки файлов на соответствие стандартам. Такие программы, как soapUI или Web Services Validation Tool for WSDL and SOAP, помогут нам выявить синтаксические ошибки, некорректные ссылки на схемы, или элементы, которые могут быть "нечитаемы" для 1С. В некоторых случаях причиной ошибки может быть:
.xsd-файлы, которые недоступны или некорректны для 1С..xsd-файлов с одинаковым targetNamespace, включающих или импортирующих друг друга, 1С может выдавать ошибку "Набор схем не может содержать схемы с одинаковыми целевыми пространствами имен". Это трудоемко, но иногда обходится ручным изменением пространств имен.WS-Policy, WS-Addressing, протокол WS-Security. Убедитесь, что ваш WSDL не содержит эти элементы, если вы используете старую версию платформы.Даже если WSDL-файл не удалось загрузить напрямую, мы можем попробовать импортировать файл .xsd в конфигурацию. Для этого:
.xsd-файл.Если импорт пройдёт успешно, в конфигурации появится новый XDTO-пакет со структурой сервиса. Это хороший знак, так как он означает, что 1С смогла разобрать схему. Однако, как мы видим из обсуждения, это не всегда решает проблему с самим WSDL-файлом и созданием WSОпределения, но это может быть полезно для дальнейшей работы с типами данных.
Если пакет со структурой сервиса появился, то вы сможете использовать его для создания объектов ФабрикаXDTO и работы с типами данных, как показано в примере:
// Предполагается, что XDTO-пакет с нужными типами уже импортирован
// В нашем случае, если WSDL не импортируется, то и WSПрокси создать не удастся
// Но если бы мы работали с XDTO-пакетом напрямую, это выглядело бы так:
// ТипСтрока = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string");
// ТипСумма = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "long");
Однако, основной вопрос остаётся: как создать WSОпределения, если WSDL-файл лежит локально и 1С его не видит?
Для того чтобы сервер 1С смог прочитать локальный WSDL-файл, который находится на клиентской машине, нам необходимо передать этот файл с клиента на сервер. Мы можем сделать это, прочитав файл на клиенте как двоичные данные, передав их на сервер, а затем записав эти двоичные данные во временный файл на сервере. После этого сервер сможет создать WSОпределения из этого временного файла.
Рассмотрим по шагам, как это реализовать:
WSОпределения: Используем путь к созданному временному файлу для инициализации объекта WSОпределения.Вот пример кода, который демонстрирует этот подход:
&НаКлиенте
Процедура ПодключитьсяКСервисуПоWSDL(Команда)
// 1. Получаем WSDL-файл как двоичные данные на клиенте
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайла.ПолноеИмяФайла = "";
ДиалогВыбораФайла.Фильтр = "WSDL-файлы (*.wsdl)|*.wsdl";
ДиалогВыбораФайла.Заголовок = "Выберите WSDL-файл";
Если ДиалогВыбораФайла.Выбрать() Тогда
ПолныйПутьКWSDLФайлу = ДиалогВыбораФайла.ПолноеИмяФайла;
Попытка
ДвоичныеДанныеWSDL = Новый ДвоичныеДанные(ПолныйПутьКWSDLФайлу);
Сообщить("WSDL-файл успешно прочитан на клиенте.");
// 2. Передаем двоичные данные на сервер и выполняем дальнейшие действия
ПодключитьсяКСервисуПоWSDLНаСервере(ДвоичныеДанныеWSDL);
Исключение
Сообщить("Ошибка при чтении WSDL-файла на клиенте: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Иначе
Сообщить("Выбор WSDL-файла отменен.");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПодключитьсяКСервисуПоWSDLНаСервере(ДвоичныеДанныеWSDL)
ПеременнаяОписание = "Подключение к веб-сервису через локальный WSDL";
Попытка
// 3. Записываем двоичные данные во временный файл на сервере
ИмяВременногоФайлаWSDL = ПолучитьИмяВременногоФайла("wsdl");
ДвоичныеДанныеWSDL.Записать(ИмяВременногоФайлаWSDL);
Сообщить("WSDL-файл записан во временный файл на сервере: " + ИмяВременногоФайлаWSDL);
// 4. Создаем WSОпределения из временного файла на сервере
Определение = Новый WSОпределения(ИмяВременногоФайлаWSDL);
Сообщить("WSОпределения успешно созданы!");
// Дальнейшая логика работы с WSПрокси
// ... (См. Шаг 3 ниже)
Исключение
Сообщить("Ошибка при создании WSОпределения на сервере: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
КонецПроцедуры
Разберем этот код подробнее:
ПодключитьсяКСервисуПоWSDL мы используем ДиалогВыбораФайла, чтобы пользователь мог интерактивно выбрать WSDL-файл на своём компьютере.ДвоичныеДанные. Этот объект позволяет нам работать с файлом как с последовательностью байтов.ПодключитьсяКСервисуПоWSDLНаСервере, передавая ей этот объект ДвоичныеДанныеWSDL.ПолучитьИмяВременногоФайла("wsdl"). Это гарантирует уникальное имя и размещение файла в системной временной директории сервера, к которой у 1С есть доступ.Записать() объекта ДвоичныеДанные мы сохраняем содержимое WSDL-файла из памяти в этот временный файл на диске сервера.WSОпределения, передавая ему путь к временному файлу на сервере.Этот подход обходит ограничение по доступу к клиентским файлам с сервера и позволяет нам работать с локально предоставленными WSDL-файлами.
После того как мы успешно создали объект WSОпределения, мы готовы к взаимодействию с веб-сервисом. Для этого нам потребуется создать объект WSПрокси, который будет представлять наш веб-сервис и его методы в 1С.
Для создания WSПрокси, нам потребуется имя сервиса и имя порта, которые обычно можно найти внутри самого WSDL-файла (или в документации от банка). В качестве конечной точки (URL) мы будем использовать адрес, предоставленный банком для реальных вызовов веб-сервиса.
// ... Продолжение процедуры ПодключитьсяКСервисуПоWSDLНаСервере после успешного создания Определения
// Примеры значений, которые нужно заменить на реальные из вашего WSDL и документации
ИмяСервиса = "ChangePasswordEIService"; // Имя сервиса из WSDL
ИмяПорта = "ChangePasswordEIPort"; // Имя порта из WSDL
// Адрес конечной точки (URL) веб-сервиса, предоставленный банком
АдресКонечнойТочки = "https://bank.example.com/services/ChangePasswordEIService"; // Замените на реальный URL
Прокси = Определение.СоздатьWSПрокси(ИмяСервиса, ИмяПорта, АдресКонечнойТочки);
Сообщить("WSПрокси успешно создан.");
// Если сервис требует аутентификации (имя пользователя/пароль)
// Прокси.Пользователь = "ИмяПользователяБанка";
// Прокси.Пароль = "ПарольПользователяБанка";
// Работа с XDTO-типами для параметров запроса
// Нам понадобится фабрика XDTO для создания объектов нужных типов
ФабрикаXDTO = Прокси.ФабрикаXDTO;
// Определяем типы данных, которые требуются для вызова метода сервиса
// Эти типы обычно описываются в XSD-схемах, на которые ссылается WSDL.
// Пример (замените на реальные типы из вашего WSDL/XSD):
// ТипЗапросСменыПароля = ФабрикаXDTO.Тип("http://ваш_namespace_банка.com", "ChangePasswordRequestIo");
// ТипСтрока = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string");
// Предположим, что у нас есть структура запроса, которую мы должны заполнить
// Например, метод ChangePasswordEIService ожидает объект типа ChangePasswordRequestIo
// Если ваш WSDL не импортировался, вы можете столкнуться с ошибкой:
// message.ChangePasswordRequest part.parameters Элемент не найден namespace: localName: ChangePasswordRequestIo
// Это означает, что 1С не смогла разобрать схему запроса.
// В таком случае нужно внимательно изучить XSD и WSDL, возможно, упростить или скорректировать их.
// Пример вызова метода (замените на реальный метод и его параметры):
// // Создаем объект запроса
// ЗапросСменыПароля = ФабрикаXDTO.Создать(ТипЗапросСменыПароля);
// ЗапросСменыПароля.Login = ФабрикаXDTO.Создать(ТипСтрока, "user123");
// ЗапросСменыПароля.OldPass = ФабрикаXDTO.Создать(ТипСтрока, "old_password");
// ЗапросСменыПароля.NewPass = ФабрикаXDTO.Создать(ТипСтрока, "new_password");
// Вызываем метод веб-сервиса
// РезультатВызова = Прокси.ChangePassword(ЗапросСменыПароля);
// Сообщаем о результате
// Сообщить("Вызов веб-сервиса завершен. Результат: " + РезультатВызова);
// В примере из сообщения 12 приводится такой вариант вызова:
// Прокси = WSСсылки.ExternalSystemCardsProcessing.СоздатьWSПрокси("ExternalSystemsProcessingService", "ExternalSystemsProcessingPort");
// ТипСтрока = Прокси.ФабрикаXDTO.Тип("string"); // Упрощенный вариант, если пространство имен известно
// ТипСумма = Прокси.ФабрикаXDTO.Тип("long");
// ТипДата = Прокси.ФабрикаXDTO.Тип("dateTime");
// Результат = Прокси.chargeOnBonusAccount(Прокси.ФабрикаXDTO.Создать(ТипСтрока, НомерКарты), Прокси.ФабрикаXDTO.Создать(ТипСумма, БонусСчет), Прокси.ФабрикаXDTO.Создать(ТипСумма, Сумма), Прокси.ФабрикаXDTO.Создать(ТипДата, ДатаПополнения));
// Мы используем объект WSОпределения, созданный динамически, а не статическую WS-ссылку.
КонецПроцедуры
Объясним ключевые моменты:
Определение.СоздатьWSПрокси(ИмяСервиса, ИмяПорта, АдресКонечнойТочки): Этот метод объекта WSОпределения создаёт наш объект WSПрокси. Мы передаём ему логические имена сервиса и порта (как они указаны в WSDL) и фактический URL-адрес, по которому находится работающий веб-сервис банка.Прокси.Пользователь и Прокси.Пароль. 1С поддерживает аутентификацию Basic, NTLM/Negotiate.Прокси.ФабрикаXDTO: Это очень важный объект. Он является центральным хранилищем всех типов данных, описанных в WSDL и XSD, которые 1С смогла разобрать. Через ФабрикаXDTO мы создаём объекты нужных типов для передачи в методы веб-сервиса. Например, ФабрикаXDTO.Тип(...) позволяет получить описание типа, а ФабрикаXDTO.Создать(...) – создать экземпляр объекта этого типа. Пространства имен (namespace) здесь критически важны.Прокси (например, Прокси.ChangePassword(ЗапросСменыПароля)).Важно помнить, что если вы столкнулись с ошибкой "Элемент не найден namespace: localName: ChangePasswordRequestIo", это прямо указывает на то, что 1С не смогла корректно разобрать XSD-схему для данного элемента. В этом случае, даже если WSDL удалось загрузить через временный файл, вам все равно придется внимательно изучать и, возможно, корректировать XSD-файлы на предмет их совместимости с 1С.
Помимо основных шагов, есть несколько важных моментов, на которые стоит обратить внимание при работе с веб-сервисами в 1С:
.wsdl или ?wsdl, чтобы проверить, возвращает ли он описание сервиса.
WS-Policy, WS-Addressing, WS-Security. Если ваш WSDL содержит эти элементы, а версия платформы старая, это может быть причиной проблем.
WSОпределения и WSПрокси при каждом вызове может замедлять работу. В этом случае, вы можете кэшировать WSDL-описание. Например, функции из БСП (Библиотеки стандартных подсистем) могут предоставлять механизмы для кэширования WSDL-файлов и проверки доступности сервиса.
Подключение к веб-сервису банка по локальному WSDL-файлу в 1С требует внимательного подхода, особенно из-за особенностей клиент-серверного взаимодействия и строгих требований платформы к формату WSDL. Путем поэтапного решения проблемы — сначала передачи WSDL-файла с клиента на сервер через двоичные данные и временный файл, а затем корректного создания WSОпределения и WSПрокси — мы можем успешно реализовать интеграцию. Всегда начинайте с проверки WSDL на внешних валидаторах и убедитесь в правильности всех пространств имён и типов данных, используемых в запросах к сервису.