Почему Web-сервис 1С не принимает определенный пакет данных и как это исправить

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

В практике интеграции 1С с внешними системами (например, WMS или системами складского учета) часто возникает ситуация, когда настроенный Web-сервис стабильно обрабатывает сотни запросов, но внезапно «спотыкается» на пакете нового типа. При этом внешняя система рапортует об успешной отправке, пакет виден в логах веб-сервера IIS, но точка останова в коде 1С даже не срабатывает. Разберемся, почему это происходит и как найти «пропавший» пакет.

Анализ механизма работы Web-сервиса 1С

Для начала проанализируем, как пакет попадает из внешней системы в 1С. Цепочка выглядит следующим образом: Внешняя система -> IIS -> Расширение 1С (wsapich.dll) -> Платформа 1С (валидация XDTO) -> Код модуля Web-сервиса.

Важно понимать, что Web-сервис в 1С — это строгая реализация протокола SOAP. Перед тем как управление будет передано в вашу функцию (например, LoadDoc(Data)), платформа должна выполнить десериализацию входящего XML-сообщения. Если на этапе этой «невидимой» проверки произойдет ошибка, платформа вернет веб-серверу ответ с кодом 500 или 400, и ваш код на языке 1С даже не начнет выполняться. Это объясняет, почему пакет виден в IIS, но «не долетает» до 1С.

Причина №1: Ошибки проверки XDTO и пространства имен

Рассмотрим разницу между «хорошим» и «плохим» пакетом из примера. В «плохом» пакете мы видим использование пространств имен (namespaces):


<cwms:STOCK xmlns:wb="http://fsrar.ru/WEGAIS/TTNSingle_v3" xmlns:ce="http://fsrar.ru/WEGAIS/CommonV3" xmlns:cwms="cwms3000.ru">

Даже если вы принимаете данные в виде строки Base64, сама структура SOAP-конверта, в который обернута эта строка, должна соответствовать описанию WSDL вашего сервиса. Если передающая система добавляет в XML-структуру атрибуты или пространства имен, которые не описаны в пакете XDTO в конфигурации 1С, платформа отвергнет запрос.

Что нужно сделать:

  1. Проверим определение Web-сервиса в Конфигураторе. Если тип входного параметра жестко задан (например, как string из пространства имен XML Schema), а прилетает сложный объект, возникнет ошибка.
  2. Если используется тип AnyType, платформа все равно пытается разобрать XML. Убедимся, что внутри Base64 не затесались символы, которые парсер 1С может интерпретировать как некорректные.
  3. Попробуем временно изменить тип входного параметра на string (если он был другим) и максимально упростить структуру.

Причина №2: Проблемы SOAP 1.2 и заголовков HTTP

Проанализируем структуру SOAP-конверта из проблемного запроса. В нем используется пространство имен http://www.w3.org/2003/05/soap-envelope, что соответствует стандарту SOAP 1.2. В то время как стандартные пакеты могут отправляться по протоколу SOAP 1.1.

Платформа 1С поддерживает оба стандарта, но они критичны к заголовку Content-Type в HTTP-запросе:

Если ВМС-система отправляет пакет SOAP 1.2 с заголовком text/xml, расширение 1С на стороне IIS может не понять, как интерпретировать данные, и прервать сессию до вызова кода 1С.

Причина №3: Настройки фильтрации в IIS

Если пакет имеет большой размер (особенно при передаче данных в Base64, который увеличивает объем данных на 33%), он может блокироваться самим веб-сервером IIS. Выясним, не срабатывают ли ограничения maxAllowedContentLength.

Также в строках Base64 могут встречаться последовательности символов, которые фильтр запросов IIS (Request Filtering) может посчитать подозрительными. Проверим файл web.config в каталоге публикации Web-сервиса. Попробуем разрешить «двойное экранирование», добавив в секцию system.webServer следующий код:


<security>
    <requestFiltering allowDoubleEscaping="true" />
</security>

Диагностика с помощью Технологического журнала

Чтобы точно «поймать» момент гибели пакета, воспользуемся Технологическим журналом (ТЖ) 1С. Это единственный способ увидеть ошибки, которые происходят на уровне платформы до исполнения программного кода.

Создадим файл logcfg.xml в папке conf сервера 1С со следующим содержанием:


<config xmlns="http://v8.1c.ru/7.4/get/logcfg">
  <log location="C:\LOGS\WEB" history="24">
    <event>
      <eq property="Name" value="EXCP"/>
    </event>
    <event>
      <eq property="Name" value="SCALL"/>
    </event>
  </log>
</config>

После этого воспроизведем отправку проблемного пакета. В логах ищем события EXCP. Если мы увидим ошибку вида Deserilization error или Несоответствие типов XDTO, значит проблема именно в структуре XML-пакета.

Радикальное решение: Переход на HTTP-сервисы

Как показывает практика и советы опытных разработчиков, для обмена произвольными данными (особенно если они уже обернуты в Base64) гораздо эффективнее использовать HTTP-сервисы вместо Web-сервисов.

Преимущества HTTP-сервисов:

Пример простой обработки данных в HTTP-сервисе:


Функция LoadDocPost(Запрос)
    ДанныеБайты = Запрос.ПолучитьТелоКакДвоичныеДанные();
    // Здесь мы можем сохранить данные в файл для анализа, если что-то идет не так
    ДанныеБайты.Записать("C:\temp\debug_packet.txt");
    
    // Преобразуем из Base64, если это необходимо
    // В HTTP-сервисе мы сами контролируем каждый шаг
    Попытка
        СтрокаXML = ПолучитьСтрокуИзДвоичныхДанных(ДанныеБайты, КодировкаТекста.UTF8);
        Результат = ОбработатьДокумент(СтрокаXML);
        Ответ = Новый HTTPСервисОтвет(200);
    Исключение
        Ответ = Новый HTTPСервисОтвет(500);
    КонецПопытки;
    
    Возврат Ответ;
КонецФункции

Резюме

Если Web-сервис «не видит» пакет, проблема почти всегда кроется в предварительной валидации SOAP-конверта. Платформа 1С более требовательна к структуре XML, чем обычный веб-сервер. Для исправления ситуации необходимо либо привести входящий пакет в полное соответствие с ожидаемой XDTO-моделью, либо (что более предпочтительно в современных реализациям) перевести интеграцию на HTTP-сервисы, которые лишены этих «родовых травм» протокола SOAP.

← На главную