При интеграции 1С со сторонними системами (например, с Microsoft Power BI или веб-приложениями) разработчики часто сталкиваются с ситуацией, когда переход по веб-ссылке опубликованного веб-сервиса возвращает лишь его техническое описание в формате WSDL либо пустой результат вместо сформированных данных. Разберем по шагам, почему возникает эта проблема, как устроена работа SOAP-протокола и какие существуют способы для правильной выгрузки XML-данных.
Выясним причину такого поведения веб-сервиса. Классический веб-сервис в 1С построен на базе протокола SOAP. Этот протокол обладает жесткими стандартами передачи информации:
?wsdl, предназначен исключительно для получения XML-схемы (Web Services Description Language), которая описывает доступные точки подключения, методы и типы входных и выходных параметров. Простой переход по ссылке через браузер или через базовый веб-коннектор формирует запрос методом HTTP GET, в ответ на который веб-сервер IIS или Apache возвращает именно файл описания.GetTable) клиент обязан отправить запрос методом HTTP POST на URL сервиса (без ?wsdl), передав в теле запроса специальный SOAP-конверт (SOAP Envelope), содержащий имя вызываемой операции и необходимые параметры.xs:string, в который помещается заранее сформированный XML-текст, платформа 1С автоматически экранирует служебные знаки. Символы < и > преобразуются в < и >. В результате принимающая сторона получает экранированную строку внутри SOAP-ответа, которую необходимо парсить повторно.+ приводит к ошибкам структуры, если значения реквизитов содержат кавычки, амперсанды или знаки неравенства.Если конечной целью является получение файла или строки XML по прямой ссылке (например, в Power BI через стандартное подключение к веб-странице без сложных сценариев аутентификации SOAP), наилучшим решением выступает создание HTTP-сервиса вместо SOAP.
Разберем по шагам создание такого сервиса в конфигураторе:
Общие -> HTTP-сервисы создадим новый сервис, например, с именем DataExport и корневым URL export./data.GET и назначим ему процедуру-обработчик в модуле сервиса.application/xml.Посмотрим на пример программного кода обработчика HTTP-сервиса:
Функция dataПолучить(Запрос)
// Формируем результирующий XML с помощью объекта ЗаписьXML
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку("UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("ДанныеЭкспорта");
// Пример заполнения данными
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Запись.ЗаписатьНачалоЭлемента("Строка");
Запись.ЗаписатьАтрибут("Период", Формат(Выборка.Период, "ДФ=yyyyMMdd"));
Запись.ЗаписатьНачалоЭлемента("НоменклатурнаяГруппа");
Запись.ЗаписатьТекст(Строка(Выборка.НоменклатурнаяГруппа));
Запись.ЗаписатьКонецЭлемента();
Запись.ЗаписатьНачалоЭлемента("Количество");
Запись.ЗаписатьТекст(Строка(Выборка.Количество));
Запись.ЗаписатьКонецЭлемента();
Запись.ЗаписатьКонецЭлемента(); // Строка
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // ДанныеЭкспорта
ТекстXML = Запись.Закрыть();
// Формируем HTTP-ответ
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(ТекстXML, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецФункции
После обновления публикации на веб-сервере данные становятся доступны по прямой ссылке вида http://сервер/база/hs/export/data. Power BI сможет прочитать такой ответ стандартным веб-коннектором без необходимости разбора SOAP-оболочек.
Если менять архитектуру нельзя и требуется использовать уже существующий SOAP веб-сервис, проанализируем, как правильно вызывать его методы со стороны клиента.
Для обращения из другой информационной базы 1С нельзя просто обращаться по HTTP. Необходимо задействовать объекты WSОпределения и WSПрокси. Рассмотрим подробнее программный код такого вызова:
// Получаем описание веб-сервиса по WSDL
wsОпр = Новый WSОпределения("http://сервер/база/ws/DataExchange.1cws?wsdl", "ПользовательWS", "ПарольWS");
// Инициализируем прокси для обращения к операциям сервиса
URIПространства = "http://www.sample-package.org";
ИмяСервиса = "DataExchange";
ТочкаПодключения = "DataExchangeSoap";
ws = Новый WSПрокси(wsОпр, URIПространства, ИмяСервиса, ТочкаПодключения);
ws.Пользователь = "ПользовательWS";
ws.Пароль = "ПарольWS";
// Вызываем метод веб-сервиса напрямую
РезультатСтрока = ws.GetTable();
// Если метод вернул сериализованный XML, считываем его
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(РезультатСтрока);
// Дальнейший разбор через ФабрикаXDTO или ЧтениеXML
Чтение.Закрыть();
Если вызов выполняется из Microsoft Power BI, настроить обращение через простой интерфейс ссылки не получится. В Power Query необходимо вручную прописать M-запрос через функцию Web.Contents, передав метод POST, заголовок SOAPAction и тело SOAP-конверта с помощью функции Text.ToBinary.
Когда основная задача заключается в быстрой передаче табличных данных в Power BI, наиболее эффективным решением является использование встроенного протокола OData платформы 1С:
УстановитьСоставСтандартногоИнтерфейсаOData().http://сервер/база/odata/standard.odata/.Этот способ полностью исключает необходимость ручного написания XML и создания сервисов в конфигурации, сохраняя типизацию полей и системную фильтрацию данных.
Если передача структурированных данных выполняется через строку, откажемся от конкатенации строк и обратимся к объектам ЗаписьXML и ФабрикаXDTO. Посмотрим на пример выгрузки через пакеты XDTO:
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
// Запись сформированного объекта XDTO
ФабрикаXDTO.ЗаписатьXML(Запись, ОбъектXDTO);
ДанныеXML = Запись.Закрыть();
Возврат ДанныеXML;
Использование специализированных объектов гарантирует корректное закрытие всех тегов, исключает сбои кодировок и автоматически экранирует недопустимые символы в значениях реквизитов.