При разработке SOAP веб-сервисов в 1С часто требуется возвращать не примитивные типы (число, строка), а сложные составные структуры данных. Для этого создается пользовательский XDTO-пакет, тип которого указывается в возвращаемом значении операции веб-сервиса. Однако при вызове такого сервиса сторонними клиентами (например, PHP) нередко возникает фатальная ошибка SoapFault exception: [Client] SOAP-ERROR: Encoding: Violation of encoding rules. Проанализируем причины этой проблемы и разберем по шагам варианты ее решения.
Самая распространенная причина ошибки кодирования SOAP заключается в том, что клиентский интерпретатор (в частности, встроенный SOAP-клиент в PHP) сохраняет WSDL-описание сервиса в локальный кэш. Если вы изменили структуру пакета XDTO или состав свойств в 1С, клиент продолжает отправлять и парсить запросы по устаревшей схеме.
Для гарантированного сброса кэша на стороне PHP во время отладки и разработки необходимо временно отключить кэширование WSDL следующими директивами:
ini_set('soap.wsdl_cache_enabled', 0);
ini_set('soap.wsdl_cache_ttl', 0);
После отключения кэша клиент начнет запрашивать актуальную схему типов непосредственно с сервера при каждом новом вызове.
Выясним, какие ошибки в коде 1С могут нарушать правила валидации XML-схемы:
xs:boolean допустимы значения true или false (а также строковые 1 и 0). При заполнении свойства объекта XDTO в 1С необходимо передавать значения типа Булево (Истина или Ложь). Передача числа 1 или 0 вместо булевого значения может привести к сбою механизма сериализации платформы.nillable="true" или minOccurs="0", оно считается строго обязательным. Передача Неопределено, Null или пропуск инициализации обязательного свойства нарушает правила схемы.Число платформа 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С.
Иногда возникает ситуация, когда после изменения XDTO-пакета и добавления новых полей объект ФабрикаXDTO.Создать() возвращает структуру без новых свойств, либо вызов функции падает с ошибкой. Рассмотрим причины такого поведения:
rphost) удерживают сессии веб-сервисов в пуле. При динамическом обновлении конфигурации или повторной публикации изменения метаданных могут не примениться к существующим процессам. Для решения требуется перезапустить веб-сервер (служба Apache или команда iisreset для IIS).Если специфика интеграции допускает модернизацию протокола взаимодействия, разберем более простые и устойчивые альтернативы:
ЗаписьJSON и ПрочитатьJSON). Это полностью исключает проблемы строгой валидации XSD-схем и сложности с кэшированием WSDL.xs:string. Внутри функции 1С формируйте JSON-строку или произвольный XML, а на стороне клиента выполняйте стандартную десериализацию полученной строки.