При работе с Web-сервисами в 1С (SOAP) разработчики нередко сталкиваются с ситуацией, когда публикация базы данных проходит без видимых проблем, однако попытка получить описание сервиса (WSDL) или вызвать конструктор WSОпределения приводит к сбою. Вместо корректной схемы веб-сервер возвращает ошибку HTTP 500 Internal Server Error или критическое сообщение Ошибка инициализации библиотеки модулей.
В этой статье мы подробно разберем основные причины возникновения этой ошибки, выясним, почему модуль Web-сервиса отказывается компилироваться на сервере, и рассмотрим пошаговое решение проблемы.
Проанализируем практический сценарий: в базе-источнике создается Web-сервис для передачи данных о документах реализации, но при вызове WSDL со стороны базы-приемника платформа генерирует сбой. Код ошибки 500 означает внутреннюю ошибку на стороне веб-сервера (IIS или Apache). В контексте платформы 1С это чаще всего вызвано одной из следующих причин:
IUSR, IIS_IUSRS) должна иметь права на чтение и выполнение в каталоге установки платформы 1С (папка bin), каталоге базы и временной папке Temp.Рассмотрим распространенную ситуацию. При обращении к WSDL через браузер или конструктор 1С выводится ошибка:
{WebСервис.tablet.Модуль(30,63)}: Ожидается символ ')'
Проанализируем фрагмент кода, из-за которого происходил сбой при установке параметров запроса:
// Ошибка: пропущены закрывающие скобки в функциях КонецДня и НачалоДня
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата);
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата);
Чтобы исправить данную ошибку, необходимо правильно расставить скобки при вызове функций работы с датой:
// Корректный вариант:
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
Второй критически важный момент — совпадение параметров в метаданных и в заголовке функции модуля Web-сервиса.
Если в конфигураторе в объекте Web-сервис для операции ПередатьРеализацию объявлен входящий параметр (например, tabletst), то заголовок функции в модуле веб-сервиса обязан принимать этот параметр.
Пример ошибочного объявления (параметр объявлен в метаданных, но отсутствует в коде):
// Ошибка: функция объявлена без параметров, хотя метаданные требуют параметр
Функция ПередатьРеализацию()
// Код обработки...
КонецФункции
Для устранения ошибки вызова и инициализации модуля передадим параметр в заголовок функции:
// Корректный заголовок функции
Функция ПередатьРеализацию(tabletst)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка,
| РеализацияТоваровУслуг.Номер,
| РеализацияТоваровУслуг.Дата,
| РеализацияТоваровУслуг.Контрагент
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|ГДЕ
| РеализацияТоваровУслуг.Проведен = ИСТИНА
| И РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНач И &ДатаКон";
Запрос.УстановитьПараметр("ДатаКон", КонецДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(ТекущаяДата()));
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
Возврат Сериализовать(РезультатЗапроса);
КонецФункции
Платформа 1С не позволяет передавать объект ТаблицаЗначений или РезультатЗапроса напрямую через Web-сервис в чистом виде, так как они не входят в базовую схему типов SOAP. Передавать данные рекомендуется в виде сериализованной XML-строки, JSON или через ХранилищеЗначения.
Рассмотрим пример вспомогательных функций для сериализации и десериализации данных с использованием СериализаторXDTO и ЗаписьXML:
Функция Сериализовать(ОбъектСериализации)
ДеревоВОбъектеXDTO = СериализаторXDTO.ЗаписатьXDTO(ОбъектСериализации);
МойXML = Новый ЗаписьXML;
МойXML.УстановитьСтроку();
ФабрикаXDTO.ЗаписатьXML(МойXML, ДеревоВОбъектеXDTO);
Возврат МойXML.Закрыть();
КонецФункции
Функция Десериализировать(XMLСтрока)
ЧтениеДанныхXML = Новый ЧтениеXML;
ЧтениеДанныхXML.УстановитьСтроку(XMLСтрока);
Результат = СериализаторXDTO.ПрочитатьXML(ЧтениеДанныхXML);
ЧтениеДанныхXML.Закрыть();
Возврат Результат;
КонецФункции
После того как синтаксические ошибки исправлены и база повторно опубликована на веб-сервере, выполняем обращение к сервису из другой базы 1С с помощью конструктора WSОпределения.
Разберем пример программного вызова:
URLСервиса = "http://myserver/UPP_Base/ws/tablet.1cws?wsdl";
Логин = "WebServices";
Пароль = "12345";
Попытка
// Создаем описание Web-сервиса
Определения = Новый WSОпределения(URLСервиса, Логин, Пароль);
// Подключаемся к прокси-сервису
WSПрокси = Новый WSПрокси(Определения, "http://www.sample-package.org", "tablet", "tabletSoap");
WSПрокси.Пользователь = Логин;
WSПрокси.Пароль = Пароль;
// Вызываем операцию
XMLРезультат = WSПрокси.ПередатьРеализацию("ВходнойПараметр");
// Десериализуем полученную таблицу
ТаблицаРеализаций = Десериализировать(XMLРезультат);
Исключение
Сообщить("Ошибка при вызове Web-сервиса: " + ОписаниеОшибки());
КонецПопытки;
WSОпределения указывается точный конечный адрес WSDL.http://имя_сервера/база/ws/имя_сервиса.1cws?wsdl в браузере. Если браузер запрашивает авторизацию и отдает структурированный XML-документ схемы, публикация прошла успешно.