Как исправить ошибку SOAP-ERROR: Encoding: Violation of encoding rules при возврате XDTO из web-сервиса 1С?

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

При разработке SOAP веб-сервисов в 1С часто требуется возвращать не примитивные типы (число, строка), а сложные составные структуры данных. Для этого создается пользовательский XDTO-пакет, тип которого указывается в возвращаемом значении операции веб-сервиса. Однако при вызове такого сервиса сторонними клиентами (например, PHP) нередко возникает фатальная ошибка SoapFault exception: [Client] SOAP-ERROR: Encoding: Violation of encoding rules. Проанализируем причины этой проблемы и разберем по шагам варианты ее решения.

Причина 1. Кэширование WSDL-схемы на стороне клиента

Самая распространенная причина ошибки кодирования SOAP заключается в том, что клиентский интерпретатор (в частности, встроенный SOAP-клиент в PHP) сохраняет WSDL-описание сервиса в локальный кэш. Если вы изменили структуру пакета XDTO или состав свойств в 1С, клиент продолжает отправлять и парсить запросы по устаревшей схеме.

Для гарантированного сброса кэша на стороне PHP во время отладки и разработки необходимо временно отключить кэширование WSDL следующими директивами:


ini_set('soap.wsdl_cache_enabled', 0);
ini_set('soap.wsdl_cache_ttl', 0);

После отключения кэша клиент начнет запрашивать актуальную схему типов непосредственно с сервера при каждом новом вызове.

Причина 2. Несоответствие типов данных 1С и схемы XSD

Выясним, какие ошибки в коде 1С могут нарушать правила валидации XML-схемы:

  1. Булевы поля (xs:boolean): В схеме XSD для типа xs:boolean допустимы значения true или false (а также строковые 1 и 0). При заполнении свойства объекта XDTO в 1С необходимо передавать значения типа Булево (Истина или Ложь). Передача числа 1 или 0 вместо булевого значения может привести к сбою механизма сериализации платформы.
  2. Пустые значения и отсутствие свойств: Если свойство в схеме не помечено признаками nillable="true" или minOccurs="0", оно считается строго обязательным. Передача Неопределено, Null или пропуск инициализации обязательного свойства нарушает правила схемы.
  3. Числа с плавающей точкой (xs:double, xs:float): При использовании числовых типов убедитесь, что в качестве разделителя дробной части используется точка. При заполнении из типа Число платформа 1С делает это автоматически, но при ручной подстановке строк с запятой сериализатор завершит работу ошибкой.

Посмотрим на пример корректного формирования сложного объекта XDTO в функции веб-сервиса:


Функция НайтиЗаказ(НомерЗаказа, Год) Экспорт
    
    ДокументЗаказТип = ФабрикаXDTO.Тип("myURI", "FindOrder"); 
    ДокументЗаказ = ФабрикаXDTO.Создать(ДокументЗаказТип);
    
    // Заполняем строго в соответствии с типами XSD
    ДокументЗаказ.IsFind = Истина; // xs:boolean требует Булево
    ДокументЗаказ.Year = СокрЛП(Год); // xs:string
    ДокументЗаказ.Number = СокрЛП(НомерЗаказа); // xs:string
    ДокументЗаказ.Total = ВыборкаДокумента.СуммаДокумента; // xs:double или xs:int
    ДокументЗаказ.UUID = Строка(ВыборкаДокумента.Ссылка.УникальныйИдентификатор());
    
    // Выполняем внутреннюю проверку объекта перед возвратом
    ДокументЗаказ.Проверить();
    
    Возврат ДокументЗаказ;
    
КонецФункции

Метод Проверить() у объекта XDTO позволяет перехватить ошибки несоответствия структуры XSD еще на этапе отладки внутри сеанса 1С.

Причина 3. Рассинхронизация XDTO-пакетов и пула соединений 1С

Иногда возникает ситуация, когда после изменения XDTO-пакета и добавления новых полей объект ФабрикаXDTO.Создать() возвращает структуру без новых свойств, либо вызов функции падает с ошибкой. Рассмотрим причины такого поведения:

  1. Кэширование пула соединений веб-сервера: Модуль расширения веб-сервера (IIS или Apache) и рабочие процессы 1С (rphost) удерживают сессии веб-сервисов в пуле. При динамическом обновлении конфигурации или повторной публикации изменения метаданных могут не примениться к существующим процессам. Для решения требуется перезапустить веб-сервер (служба Apache или команда iisreset для IIS).
  2. Проверка привязки пакета к сервису: Убедитесь, что используемый пользовательский XDTO-пакет явно добавлен в свойство веб-сервиса Пакеты XDTO в дереве метаданных конфигуратора.
  3. Тестирование через независимые утилиты: Для изоляции проблемы используйте специализированные инструменты тестирования SOAP-сервисов (например, SoapUI), отключая в них кэширование ответов. Это позволит локализовать проблему — находится ли она на стороне генерации WSDL в 1С или в клиенте-потребителе сервиса.

Альтернативные архитектурные решения

Если специфика интеграции допускает модернизацию протокола взаимодействия, разберем более простые и устойчивые альтернативы:

  1. Использование HTTP-сервисов (REST API): Переход на встроенные HTTP-сервисы 1С с передачей данных в формате JSON (объекты ЗаписьJSON и ПрочитатьJSON). Это полностью исключает проблемы строгой валидации XSD-схем и сложности с кэшированием WSDL.
  2. Возврат сериализованной строки: Если требуется сохранить SOAP веб-сервис, измените тип возвращаемого значения функции на простой xs:string. Внутри функции 1С формируйте JSON-строку или произвольный XML, а на стороне клиента выполняйте стандартную десериализацию полученной строки.
← На главную