При работе с внешними веб-сервисами в платформе 1С:Предприятие часто возникает задача получить данные из сторонней системы. Однако при попытке инициализировать WSDL-схему с помощью конструктора WSОпределения программисты сталкиваются с ошибкой вида «Неверный формат. message.GetDataTableHttpPostOut part.Body Тип части сообщения не задан». Разберем причинно-следственную связь этой проблемы и рассмотрим пошаговый алгоритм её диагностики и решения.
Сформулируем, почему платформа 1С выдает подобное сообщение. Проблема заключается в особенностях генерации WSDL-документов веб-сервисами, созданными на платформе Microsoft .NET (файлы с расширением .asmx).
Сервисы .NET по умолчанию формируют описание WSDL сразу для нескольких протоколов: SOAP 1.1, SOAP 1.2, HTTP GET и HTTP POST. В блоках, описывающих протоколы HTTP GET и HTTP POST, автоматически создаются служебные сообщения (например, GetDataTableHttpGetOut и GetDataTableHttpPostOut), в которых присутствуют теги <wsdl:part name="Body" /> без явного указания типа данных (отсутствуют атрибуты type или element).
Встроенный валидатор WSDL в 1С строго анализирует весь документ полностью, включая неиспользуемые секции. Встретив элемент part без типа данных, платформа прерывает считывание схемы и генерирует исключение Неверный формат.
Перед тем как править схему или менять код в 1С, необходимо убедиться, что сетевой доступ к веб-сервису функционирует корректно и проблема не связана с настройками сети или авторизацией.
?WSDL в конце ссылки. Если браузер не открывает XML-дерево схемы, значит, проблема в сети: заблокирован IP-адрес, требуется прокси-сервер или авторизация на уровне веб-сервера.rphost). Если в браузере на клиенте ссылка открывается, а в 1С на сервере нет — проверьте сетевые доступы и настройки прокси для сервера 1С.Самый простой и эффективный способ обойти жесткие ограничения валидатора 1С — скачанный WSDL-файл с удаленными HTTP-binding секциями.
.wsdl или .xml.<wsdl:message>, вызывающие ошибку, — все сообщения, содержащие в названии HttpPostOut и HttpGetOut. Также можно удалить секции <wsdl:binding> и <wsdl:port>, относящиеся к HTTP-GET и HTTP-POST, оставив только SOAP.<wsdl:part name="Body" /> и вручную дописать тип данных, например: <wsdl:part name="Body" type="s:string" />.WSОпределения.Рассмотрим пример кода 1С с загрузкой локального WSDL-файла:
ПутьКФайлуWSDL = "C:\WS\Airspace.wsdl";
Пользователь = "ЛогинСервиса";
Пароль = "ПарольСервиса";
Попытка
// Загружаем исправленное локальное определение WSDL
Определение = Новый WSОпределения(ПутьКФайлуWSDL, Пользователь, Пароль);
// Создаем прокси для обращения к SOAP-сервису
WSПрокси = Новый WSПрокси(Определение, "http://tempuri.org/", "Airspace", "AirspaceSoap");
WSПрокси.Пользователь = Пользователь;
WSПрокси.Пароль = Пароль;
// Вызываем нужную функцию веб-сервиса
Результат = WSПрокси.GetAirspaceData(ТокенАвторизации);
Исключение
Сообщить("Ошибка при вызове веб-сервиса: " + ОписаниеОшибки());
КонецПопытки;
Если WSDL-схема часто меняется на стороне поставщика или нет возможности хранить файл на диске, откажемся от механизмов WSОпределения и WSПрокси в пользу прямых HTTP-запросов. Мы сформируем SOAP XML-конверт вручную и отправим его через объект HTTPСоединение.
Проанализируем пример выполнения прямого SOAP-запроса:
Сервер = "websvc.matfmc.ru";
АдресРесурса = "/CBD2/1.0/Airspace.asmx";
// Формируем текст SOAP-конверта
ТекстЗапросаXML =
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
| xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
| xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
| <soap:Body>
| <GetAirspaceData xmlns=""http://tempuri.org/"">
| <token>" + ТокенАвторизации + "</token>
| </GetAirspaceData>
| </soap:Body>
|</soap:Envelope>";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Заголовки.Вставить("SOAPAction", "http://tempuri.org/GetAirspaceData");
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстЗапросаXML, КодировкаТекста.UTF8);
HTTPСоединение = Новый HTTPСоединение(Сервер);
Попытка
ОтветHTTP = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если ОтветHTTP.КодСостояния = 200 Тогда
ТекстОтветаXML = ОтветHTTP.ПолучитьТелоКакСтроку();
// Разбираем полученный XML через ЧтениеXML
Иначе
Сообщить("Ошибка HTTP: " + ОтветHTTP.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Ошибка соединения: " + ОписаниеОшибки());
КонецПопытки;
Если у вашей команды есть доступ к серверу, где развернут веб-сервис, проблему можно решить системно. В файле конфигурации web.config .NET-приложения достаточно отключить протоколы HTTP-GET и HTTP-POST для генерации WSDL, оставив только SOAP.
Для этого в секции <system.web> файла web.config необходимо ограничить протоколы:
<webServices>
<protocols>
<remove name="HttpGet" />
<remove name="HttpPost" />
</protocols>
</webServices>
После внесения этого изменения веб-сервис начнет отдавать чистый WSDL, который без ошибок обрабатывается встроенным объектом WSОпределения в 1С.