Как правильно прочитать входной параметр web-сервиса через XDTO в 1С?

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

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

Проанализируем ситуацию: почему не работает ФабрикаXDTO.ПрочитатьXML

Довольно часто разработчики описывают обработчик метода веб-сервиса следующим образом:


Функция Test(ParamIn)
    ТипXDTO = ФабрикаXDTO.Тип("urn.xx.xx.stbdeviceinfo","Objects");
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ParamIn, ТипXDTO);
КонецФункции

При выполнении этого кода возникает ошибка, так как платформа сообщает, что переменная ParamIn не является объектом типа ЧтениеXML. Выясним причину такого поведения.

Дело в том, что платформа 1С при вызове веб-сервиса берет на себя всю работу по парсингу входящего XML-документа. Этот процесс называется автоматической десериализацией. Если тип параметра веб-сервиса жестко задан в конфигурации с привязкой к определенному пакету XDTO, то в обработчик метода параметр приходит уже в виде готового объекта платформы.

Следовательно, ручной разбор XML не требуется. Входящий параметр уже представляет собой ОбъектXDTO, СписокXDTO или ЗначениеXDTO (для примитивных типов). Правильный доступ к объекту выглядит максимально просто:


Функция Test(ParamIn)
    // Входящий параметр уже является готовым объектом XDTO
    ОбъектXDTO = ParamIn;
    // Далее сразу работаем с его свойствами
КонецФункции

Решение проблемы: Ошибка "Итератор не определен"

После того как мы выяснили, что параметр уже готов к использованию, возникает следующая типичная проблема. Допустим, мы ожидаем получить массив объектов и пытаемся обойти его в цикле:


Для Каждого Запись Из ParamIn.Objects Цикл
    // Обработка записи
КонецЦикла;

Однако система прерывает выполнение с ошибкой «итератор не определен». Проанализируем причину. Эта ошибка означает, что свойство Objects было распознано платформой как одиночный ОбъектXDTO, а не как коллекция. Соответственно, цикл по нему запустить невозможно.

Чтобы 1С корректно распознала массив элементов и сформировала тип СписокXDTO (который поддерживает использование итератора и цикла Для Каждого), необходимо правильно настроить сам пакет XDTO в дереве конфигурации. Разберем по шагам, что нужно сделать:

  1. Откройте пакет XDTO в дереве метаданных конфигурации 1С.
  2. Найдите тип объекта и выберите нужное свойство (в нашем случае это Objects), которое должно являться коллекцией элементов.
  3. В палитре свойств найдите параметр «Максимальное количество».
  4. По умолчанию там может стоять значение 1. Измените его на -1 (что означает неограниченное количество) или любое необходимое число больше единицы.

После сохранения этих изменений, если в XML приходит несколько элементов, платформа создаст именно коллекцию СписокXDTO. Теперь обход списка будет работать корректно и без ошибок.

Методы диагностики и отладки входящих параметров

При отладке веб-сервисов штатный отладчик 1С не всегда перехватывает вызовы (это может зависеть от настроек сервера или наличия балансировщиков нагрузки). Посмотрим на пример того, как можно надежно определить структуру и тип пришедшего параметра без остановки кода:

  1. Запись в журнал регистрации: Добавьте в начало вашего метода строку для логирования типа. Это сразу даст понимание, какой объект реально пришел на вход:
    
    ЗаписьЖурналаРегистрации("WebСервис.Test", 
        УровеньЖурналаРегистрации.Информация, 
        , 
        , 
        "Тип параметра: " + Строка(ТипЗнч(ParamIn)));
    
  2. Использование встроенного метода Тип(): У самих объектов XDTO есть метод Тип(). Если вызвать ParamIn.Тип(), метод вернет системный объект ТипОбъектаXDTO. Из него можно программно извлечь имя типа и URI пространства имен для дополнительного контроля:
    
    ИнфоОТипе = ParamIn.Тип();
    ИмяТипа = ИнфоОТипе.Имя;
    URIПространстваИмен = ИнфоОТипе.URIПространстваИмен;
    

Работа с неструктурированными данными

Рассмотрим альтернативный сценарий. Что делать, если входящий XML заранее неизвестен, либо его структура может динамически меняться, и мы не можем жестко привязать тип параметра к XDTO-пакету?

В таком случае в свойствах параметра веб-сервиса (прямо в конфигураторе) следует установить тип ValueStorage (ХранилищеЗначения) или использовать обычную Строка. И только при таком подходе внутри метода мы используем ручной разбор, читая строковые данные через объект ЧтениеXML:


Функция Test(ParamIn)
    // В данном случае ParamIn ожидаем в виде строки с произвольным XML
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(ParamIn);
    
    // Самостоятельно читаем данные через фабрику XDTO
    ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);
    Возврат ОбъектXDTO;
КонецФункции

Подводя итоги, при работе со строго типизированными веб-сервисами в 1С всегда доверяйте платформе — она самостоятельно выполняет десериализацию и передает вам готовый объект. Главное — правильно описать структуру данных в пакете XDTO, уделяя особое внимание свойствам с множественными значениями (свойство "Максимальное количество").

← На главную