Как подключиться к веб-сервису банка, используя локальный WSDL-файл в 1С?

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

При интеграции с внешними системами, такими как банковские веб-сервисы, мы часто сталкиваемся с необходимостью подключения по WSDL-файлу, предоставленному контрагентом. В идеальном мире банк предоставил бы ссылку на веб-сервис, и мы могли бы легко добавить её в 1С. Однако, как показывает практика, нередко нам присылают локальные файлы .wsdl и .xsd, а попытка подключиться к веб-сервису 1С по такому локальному файлу через конструкцию Новый WSОпределения("file://C:/путь/к/файлу.wsdl") выдаёт ошибку "Неверный формат" или другие неочевидные сообщения. Рассмотрим эту проблему подробнее и выясним, как её решить.

В чем заключается основная проблема?

Главная трудность возникает из-за двух основных факторов:

  1. Строгие требования 1С к формату WSDL/XSD: Платформа 1С очень чувствительна к корректности и соответствию стандартам WSDL- и XSD-файлов. Даже если файл кажется валидным для других инструментов, 1С может найти в нём "вольности" или неподдерживаемые конструкции (например, упоминания WS-Policy, WS-Addressing, WS-Security в версиях 8.3.7 и ниже, или некорректные пространства имён).
  2. Особенности клиент-серверного взаимодействия в 1С: Когда мы пишем код Новый WSОпределения("file://C:/..."), мы обычно запускаем его на сервере (например, в серверной процедуре &НаСервере). Однако путь C:/... относится к локальной файловой системе клиентской машины, а не сервера. Сервер 1С не имеет доступа к файлам, расположенным на локальном диске пользователя. Это приводит к тому, что сервер просто не может найти и прочитать указанный файл, даже если он совершенно корректен.

Именно проблема клиент-серверного взаимодействия часто является камнем преткновения, приводящим к ошибкам вида "Неверный формат" или "Элемент не найден", так как система пытается парсить несуществующий или некорректно прочитанный файл.

Шаг 1: Предварительная проверка и импорт XDTO-пакетов (если возможно)

Прежде чем погружаться в более сложные решения, давайте убедимся, что наши файлы .wsdl и .xsd максимально корректны и, по возможности, попробуем использовать встроенные механизмы 1С.

Проверка WSDL/XSD файлов

Поскольку 1С не имеет встроенного валидатора WSDL, мы рекомендуем использовать сторонние инструменты для проверки файлов на соответствие стандартам. Такие программы, как soapUI или Web Services Validation Tool for WSDL and SOAP, помогут нам выявить синтаксические ошибки, некорректные ссылки на схемы, или элементы, которые могут быть "нечитаемы" для 1С. В некоторых случаях причиной ошибки может быть:

  1. Использование слова "policies" в WSDL. Попробуйте удалить все упоминания этого слова в XML-редакторе.
  2. Наличие ссылок на .xsd-файлы, которые недоступны или некорректны для 1С.
  3. Ошибка "WSDL должен содержать элемент definitions" указывает, что файл либо не является валидным XML, либо не соответствует структуре WSDL.
  4. При наличии нескольких .xsd-файлов с одинаковым targetNamespace, включающих или импортирующих друг друга, 1С может выдавать ошибку "Набор схем не может содержать схемы с одинаковыми целевыми пространствами имен". Это трудоемко, но иногда обходится ручным изменением пространств имен.
  5. Версии 1С:Предприятие 8.3.7 и более ранние не поддерживают механизмы WS-Policy, WS-Addressing, протокол WS-Security. Убедитесь, что ваш WSDL не содержит эти элементы, если вы используете старую версию платформы.

Импорт XSD-схемы в XDTO-пакеты

Даже если WSDL-файл не удалось загрузить напрямую, мы можем попробовать импортировать файл .xsd в конфигурацию. Для этого:

  1. Откроем конфигурацию в режиме Конфигуратор.
  2. Перейдём в раздел Общие -> XDTO-пакеты.
  3. Нажмём кнопку Импорт XML-схемы... и выберем наш .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С его не видит?

Шаг 2: Решение проблемы доступа к локальному WSDL-файлу (Клиент-Серверное взаимодействие)

Для того чтобы сервер 1С смог прочитать локальный WSDL-файл, который находится на клиентской машине, нам необходимо передать этот файл с клиента на сервер. Мы можем сделать это, прочитав файл на клиенте как двоичные данные, передав их на сервер, а затем записав эти двоичные данные во временный файл на сервере. После этого сервер сможет создать WSОпределения из этого временного файла.

Рассмотрим по шагам, как это реализовать:

  1. На стороне клиента: Читаем содержимое WSDL-файла в двоичные данные.
  2. Передаём данные на сервер: Вызываем серверную процедуру, передавая ей полученные двоичные данные WSDL-файла.
  3. На стороне сервера: Сохраняем полученные двоичные данные во временный файл.
  4. Создаём 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Определения на сервере: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
КонецПроцедуры

Разберем этот код подробнее:

  1. В клиентской процедуре ПодключитьсяКСервисуПоWSDL мы используем ДиалогВыбораФайла, чтобы пользователь мог интерактивно выбрать WSDL-файл на своём компьютере.
  2. После выбора файла, его содержимое считывается в объект ДвоичныеДанные. Этот объект позволяет нам работать с файлом как с последовательностью байтов.
  3. Затем мы вызываем серверную процедуру ПодключитьсяКСервисуПоWSDLНаСервере, передавая ей этот объект ДвоичныеДанныеWSDL.
  4. На сервере мы получаем имя временного файла с помощью функции ПолучитьИмяВременногоФайла("wsdl"). Это гарантирует уникальное имя и размещение файла в системной временной директории сервера, к которой у 1С есть доступ.
  5. Методом Записать() объекта ДвоичныеДанные мы сохраняем содержимое WSDL-файла из памяти в этот временный файл на диске сервера.
  6. И только после этого мы можем безопасно и корректно инициализировать объект WSОпределения, передавая ему путь к временному файлу на сервере.

Этот подход обходит ограничение по доступу к клиентским файлам с сервера и позволяет нам работать с локально предоставленными WSDL-файлами.

Шаг 3: Создание WSПрокси и вызов методов сервиса

После того как мы успешно создали объект 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-ссылку.
        
КонецПроцедуры

Объясним ключевые моменты:

  1. Определение.СоздатьWSПрокси(ИмяСервиса, ИмяПорта, АдресКонечнойТочки): Этот метод объекта WSОпределения создаёт наш объект WSПрокси. Мы передаём ему логические имена сервиса и порта (как они указаны в WSDL) и фактический URL-адрес, по которому находится работающий веб-сервис банка.
  2. Аутентификация: Если банк требует аутентификацию (например, базовую), мы можем указать Прокси.Пользователь и Прокси.Пароль. 1С поддерживает аутентификацию Basic, NTLM/Negotiate.
  3. Прокси.ФабрикаXDTO: Это очень важный объект. Он является центральным хранилищем всех типов данных, описанных в WSDL и XSD, которые 1С смогла разобрать. Через ФабрикаXDTO мы создаём объекты нужных типов для передачи в методы веб-сервиса. Например, ФабрикаXDTO.Тип(...) позволяет получить описание типа, а ФабрикаXDTO.Создать(...) – создать экземпляр объекта этого типа. Пространства имен (namespace) здесь критически важны.
  4. Вызов метода сервиса: После того как параметры запроса сформированы как XDTO-объекты, мы можем вызвать нужный метод через объект Прокси (например, Прокси.ChangePassword(ЗапросСменыПароля)).

Важно помнить, что если вы столкнулись с ошибкой "Элемент не найден namespace: localName: ChangePasswordRequestIo", это прямо указывает на то, что 1С не смогла корректно разобрать XSD-схему для данного элемента. В этом случае, даже если WSDL удалось загрузить через временный файл, вам все равно придется внимательно изучать и, возможно, корректировать XSD-файлы на предмет их совместимости с 1С.

Дополнительные рекомендации и потенциальные проблемы

Помимо основных шагов, есть несколько важных моментов, на которые стоит обратить внимание при работе с веб-сервисами в 1С:

  1. Адрес конечной точки (URL) сервиса: Убедитесь, что адрес конечной точки, предоставленный банком, является рабочим и корректным. Даже при работе с локальным WSDL, для выполнения реальных операций с веб-сервисом потребуется доступ к его сетевому адресу. Попробуйте в браузере добавить к адресу сервиса .wsdl или ?wsdl, чтобы проверить, возвращает ли он описание сервиса.
  2. Версия платформы 1С: Мы уже упоминали, что старые версии платформы (до 8.3.7) могут не поддерживать некоторые современные стандарты, такие как WS-Policy, WS-Addressing, WS-Security. Если ваш WSDL содержит эти элементы, а версия платформы старая, это может быть причиной проблем.
  3. Кэширование WSDL-описания: Если вы часто обращаетесь к веб-сервису, динамическое создание WSОпределения и WSПрокси при каждом вызове может замедлять работу. В этом случае, вы можете кэшировать WSDL-описание. Например, функции из БСП (Библиотеки стандартных подсистем) могут предоставлять механизмы для кэширования WSDL-файлов и проверки доступности сервиса.
  4. Размер передаваемых данных: При передаче больших объемов данных через веб-сервис, обратите внимание на ограничения веб-сервера (IIS, Apache), на котором размещен ваш веб-сервис, по максимальному размеру SOAP-сообщения.
  5. Отладка: Для тестирования веб-сервисов в 1С существуют специальные обработки, например "ТестПроизвольногоВебСервиса.epf", которые могут помочь в отладке взаимодействия.

Заключение

Подключение к веб-сервису банка по локальному WSDL-файлу в 1С требует внимательного подхода, особенно из-за особенностей клиент-серверного взаимодействия и строгих требований платформы к формату WSDL. Путем поэтапного решения проблемы — сначала передачи WSDL-файла с клиента на сервер через двоичные данные и временный файл, а затем корректного создания WSОпределения и WSПрокси — мы можем успешно реализовать интеграцию. Всегда начинайте с проверки WSDL на внешних валидаторах и убедитесь в правильности всех пространств имён и типов данных, используемых в запросах к сервису.

← На главную