Почему параметр функции веб-сервиса 1С получает тип XDTO anyType вместо ожидаемого?

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

При разработке интеграций на платформе 1С, особенно с использованием веб-сервисов, мы часто сталкиваемся с необходимостью обмена сложными структурами данных. Для этого в 1С используется механизм XDTO (XML Data Transfer Objects), который позволяет описывать структуры данных в виде схем и работать с ними как с обычными объектами 1С. Однако иногда возникают ситуации, когда вместо ожидаемого, строго типизированного XDTO-объекта, наш веб-сервис получает параметр типа {http://www.w3.org/2001/XMLSchema}anyType. Давайте разберем, почему это происходит и как решить эту распространенную проблему.

Представим типовую ситуацию, когда у нас есть веб-сервис с функцией, принимающей XDTO-объект:


Функция SetTaskData(TaskData)
    // Внутри этой функции TaskData.Тип() возвращает anyType
    // Вместо ожидаемого {artasks_XDTO}TaskData
КонецФункции

Здесь TaskData должен быть объектом XDTO из пакета "artasks_XDTO". Однако, при проверке внутри функции, TaskData.Тип() неожиданно возвращает {http://www.w3.org/2001/XMLSchema}anyType. При этом, если мы создадим такой объект через ФабрикуXDTO вручную, его тип будет корректным:


ТипЗадача = ФабрикаXDTO.Тип("artasks_XDTO","TaskData");
xdtoЗадача = ФабрикаXDTO.Создать(ТипЗадача);
// xdtoЗадача.Тип() = {artasks_XDTO}TaskData – вот этот тип мы и ожидаем!

Рассмотрим пример SOAP-запроса, который вызывает такую проблему:



    
    
        
            
                33333
                1668058686
                07bb51fc-a773-489a-91e6-8b03712a9120
                1668058686_1669012840
                
                Тест с набл и тэгами
                080e35c6-5adf-11e5-9bad-0025909346cf
                
                    b4a60dd7-2a54-11eb-b009-005056b6af6b
                    8883dd1b-588a-11e5-9bad-0025909346cf
                
                30740b48-5aa3-11ed-930f-00155d0b7f07
                30740b48-5aa3-11ed-930f-00155d0b7f07
                
                    3a121311-da60-11eb-92f1-00155d0b1a00
                    30740b48-5aa3-11ed-930f-00155d0b7f07
                
                
                1668988800
                1669042800
                
                
                false
                false
                false
                
                
            
        
    

В этой ситуации 1С не может однозначно сопоставить входящий XML с ожидаемым XDTO-типом artasks_XDTO.TaskData, и поэтому десериализует его как универсальный anyType. Давайте выясним, почему это происходит и как это исправить.

Анализируем причину получения anyType

Тип {http://www.w3.org/2001/XMLSchema}anyType является базовым типом для всех XDTO-объектов. Когда платформа 1С получает XML-данные, предназначенные для параметра веб-сервиса, она пытается десериализовать их в соответствии с ожидаемым XDTO-типом. Если процесс сопоставления входящего XML со схемой XDTO завершается неудачей, 1С не может распознать структуру как конкретный тип и по умолчанию присваивает ей anyType. Это сигнал о том, что между тем, что мы отправляем, и тем, что ожидает 1С, есть расхождение.

Мы рассмотрим несколько ключевых областей, где могут скрываться причины этой проблемы:

  1. Настройки веб-сервиса и окружения: Убедимся, что все необходимые конфигурации выполнены корректно, и изменения вступили в силу.

  2. Детальный разбор XML-запроса и XDTO-схемы: Проверим, насколько точно структура и содержимое нашего XML-запроса соответствуют описанию XDTO-типа в 1С. Это, как мы увидим далее, является наиболее частой причиной.

  3. Обработка необязательных и пустых полей: Разберем, как правильно передавать пустые значения или пропускать необязательные поля в XML.

Проверяем настройки и окружение

Прежде чем углубляться в структуру XML, давайте убедимся, что базовая настройка веб-сервиса выполнена правильно. Некоторые проблемы могут быть вызваны простыми недочетами в конфигурации или отсутствием ее обновления.

Перезапуск веб-сервера

После любых изменений в конфигурации 1С, касающихся XDTO-пакетов, веб-сервисов или их методов, критически важно перезапустить веб-сервер, на котором опубликована информационная база. Это может быть IIS или Apache. Почему это так важно? Платформа 1С кэширует WSDL-описания и XDTO-схемы веб-сервисов. Если мы внесли изменения (например, добавили новое свойство в XDTO-тип или изменили его структуру), но не перезапустили веб-сервер, он будет продолжать использовать старые, кэшированные описания. В результате, даже если в конфигурации 1С все правильно, веб-сервер будет "ожидать" старую структуру, и входящий запрос с новой структурой не сможет быть корректно десериализован.

Пользователь в своем случае уже попробовал перезапуск веб-сервера, но это не помогло. Это указывает на то, что проблема лежит глубже, скорее всего, в несоответствии самого XML или схеме XDTO, но этот шаг всегда должен быть первым в списке проверок.

Настройка пакетов XDTO в свойствах веб-сервиса

Необходимо убедиться, что в свойствах нашего веб-сервиса, на вкладке "Прочее" (или аналогичной, в зависимости от версии платформы), указаны все необходимые XDTO-пакеты, которые используются в его операциях. Если XDTO-пакет "artasks_XDTO" не указан в этом списке, платформа 1С может просто не "знать" о существовании типа TaskData из этого пакета при обработке входящих запросов. В таком случае, она не сможет найти соответствующую схему для десериализации и, по умолчанию, использует anyType.

Для проверки выполните следующие шаги:

  1. Откройте конфигуратор 1С.

  2. Перейдите в ветку "Веб-сервисы" (или "HTTP-сервисы", в зависимости от типа используемого сервиса).

  3. Откройте свойства вашего веб-сервиса (например, "ws.ar-mobile-tasks").

  4. Найдите вкладку "Прочее" (или похожую, например, "XDTO-пакеты").

  5. Убедитесь, что пакет "artasks_XDTO" присутствует в списке используемых пакетов.

Если пакет отсутствует, добавьте его, сохраните конфигурацию и обязательно перезапустите веб-сервер.

Пространства имен (Namespace URI)

Пространства имен в XML играют ключевую роль в уникальной идентификации элементов и типов данных. В нашем XML-запросе мы видим префикс art:, который ассоциирован с URI "artasks_XDTO" (xmlns:art="artasks_XDTO"). Крайне важно, чтобы этот URI точно совпадал с URI, который указан в свойствах самого XDTO-пакета "artasks_XDTO" в конфигурации 1С. Любое несовпадение, даже в регистре символов, приведет к тому, что 1С не сможет найти соответствующий пакет и тип.

Также следует обратить внимание на общепринятую практику: URI пространства имен часто выглядят как URL (например, http://ar.tasks), даже если они не являются реально существующими веб-адресами. Это делается для обеспечения уникальности идентификаторов в глобальном контексте XML. Хотя 1С позволяет использовать и более простые строки, использование URL-подобных URI может помочь избежать некоторых "артефактов", о которых упоминал один из участников обсуждения.

Детальный разбор XML-запроса и XDTO-схемы: Ключевое решение

Как оказалось в обсуждаемой теме, основная причина проблемы крылась в несоответствии между отправляемым XML-запросом и ожидаемой XDTO-схемой. 1С является достаточно строгой в отношении соответствия входящих данных их описанию. Давайте рассмотрим эти аспекты подробнее.

Соблюдение порядка тегов

Этот пункт был одним из решающих для автора проблемы. Для XDTO-типов, определенные как "последовательные" (sequence в XSD), порядок элементов в XML-запросе является критически важным. Если в нашем XDTO-пакете тип TaskData определен, например, со следующей последовательностью элементов:

  1. orgCode
  2. dbID
  3. author
  4. ... и так далее.

То и в XML-запросе эти элементы должны идти именно в такой последовательности. Если мы поменяем их местами, например, отправим до , 1С не сможет правильно распознать структуру объекта. Несмотря на то, что в некоторых XML-схемах порядок элементов может быть нестрогим (например, если используется all или choice в XSD), по умолчанию многие инструменты и, в частности, 1С, ожидают последовательное соответствие.

Чтобы проверить порядок тегов, необходимо открыть XDTO-пакет "artasks_XDTO" в конфигураторе 1С, выбрать тип TaskData и посмотреть на порядок свойств, указанных для этого типа. Убедитесь, что ваш XML-запрос точно воспроизводит этот порядок.

Чувствительность XML к регистру

Вторым, не менее важным аспектом, ставшим причиной проблемы, является строгая чувствительность XML к регистру символов. Это означает, что для XML и — это совершенно разные элементы. Аналогично, если в XDTO-схеме свойство называется orgCode (с маленькой буквы), а в XML-запросе мы передадим его как (с большой буквы), 1С не сможет сопоставить этот элемент с ожидаемым свойством. Это одна из самых частых ошибок, приводящих к некорректной десериализации.

Внимательно просмотрите ваш XML-запрос и убедитесь, что каждое имя тега и атрибута в XML полностью соответствует имени соответствующего свойства в XDTO-схеме, включая регистр. Это касается как корневого элемента параметра (например, , где TaskData должно совпадать с именем параметра функции), так и всех вложенных элементов (, и т.д.).

Анализ примера XML-запроса

Давайте еще раз взглянем на предоставленный XML-запрос с учетом этих правил:



    
    
        
            
                33333
                1668058686
                07bb51fc-a773-489a-91e6-8b03712a9120
                
            
        
    

Здесь мы видим, что корневой элемент параметра TaskData находится внутри элемента (это имя операции веб-сервиса). Внутри находятся элементы с префиксом art: (, и т.д.), которые соответствуют полям нашего XDTO-объекта.

Для успешной десериализации:

  1. Имя элемента TaskData (внутри ) должно точно соответствовать имени параметра функции SetTaskData(TaskData).

  2. Пространство имен artasks_XDTO (присвоенное префиксу art:) должно точно совпадать с URI XDTO-пакета в 1С.

  3. Порядок всех дочерних элементов , , и т.д. должен точно соответствовать порядку свойств в описании XDTO-типа TaskData в 1С.

  4. Регистр каждого имени тега (например, orgCode, dbID, author) должен быть идентичен регистру соответствующих свойств в XDTO-типе TaskData.

Любое отклонение в этих пунктах приведет к тому, что 1С не сможет найти подходящую схему и десериализует объект как anyType.

Обработка необязательных и пустых полей в XDTO

Автор проблемы также задал важный вопрос о том, можно ли пропускать поля в XML, если в XDTO указано, что поле может быть пустым. Давайте разберем этот нюанс, так как он часто вызывает путаницу.

Пропуск тегов (не указывать вообще)

Чтобы элемент можно было полностью пропустить (не указывать его в XML-запросе), в XDTO-схеме для соответствующего свойства должно быть установлено минимальное количество вхождений (minOccurs) в 0. По умолчанию, если minOccurs не указано, оно равно 1, что означает, что элемент является обязательным и должен присутствовать в XML. Если элемент обязателен, но отсутствует в XML, это может привести к ошибке десериализации или, в лучшем случае, к получению anyType.

Если свойство в XDTO имеет minOccurs="0", мы можем просто не включать соответствующий тег в наш XML-запрос, и 1С корректно обработает это как отсутствие значения.

Передача пустых значений (пустой тег)

Существуют несколько способов передачи "пустых" значений:

  1. Пустой самозакрывающийся тег с атрибутом xsi:nil="true": Это стандартный XML Schema способ указать, что элемент присутствует, но его значение является "nil" (ничто), а не пустой строкой. Для этого свойство в XDTO-схеме должно быть помечено как "Допускает пустое значение" (nillable="true" в XSD). Пример:

    
    
    

    Здесь xsi - это префикс для пространства имен XML Schema Instance (xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"). Это означает, что поле явно существует, но его значение отсутствует. В 1С такое значение будет интерпретировано как Неопределено.

  2. Обычный пустой тег: Если мы хотим передать пустую строку для строкового поля или 0 для числового, мы можем использовать обычный пустой тег:

    
    
    

    или

    
    
    

    В 1С это будет интерпретировано как пустая строка для строковых типов, 0 для числовых, Ложь для булевых и т.д., в зависимости от типа свойства. Такой подход не требует атрибута xsi:nil="true" и используется, когда мы хотим передать именно "пустое" значение, а не его отсутствие (Неопределено).

Таким образом, важно различать: хотим ли мы пропустить элемент полностью (для чего нужно minOccurs="0" в схеме) или же хотим передать "пустое" или "неопределенное" значение (для чего используются пустые теги или xsi:nil="true" в зависимости от желаемого результата и настроек nillable в схеме).

Инструменты отладки

Для диагностики подобных проблем с веб-сервисами и XDTO крайне полезно использовать специализированные инструменты:

  1. SoapUI: Это мощный инструмент для тестирования SOAP- и REST-сервисов. Он позволяет отправлять запросы, просматривать ответы, валидировать XML по WSDL-схемам. С его помощью мы можем убедиться, что формируемый клиентский запрос соответствует ожиданиям сервера, а также увидеть полный текст запроса и ответа.

  2. Отладчик 1С: Подключите отладчик к веб-сервису 1С и установите точку останова в начале функции SetTaskData. Это позволит нам пошагово выполнить код и проверить значение TaskData.Тип(), а также просмотреть структуру полученного объекта.

  3. Логирование веб-сервера: Если веб-сервис опубликован на IIS или Apache, мы можем настроить логирование входящих HTTP-запросов. Это позволит нам увидеть полный текст XML-запроса, который действительно дошел до сервера, и сравнить его с тем, что мы отправляли, выявляя возможные искажения или ошибки передачи.

Заключение

Проблема получения anyType вместо ожидаемого XDTO-типа в параметре функции веб-сервиса 1С является достаточно распространенной, но, как мы выяснили, имеет четкие причины и решения. Ключевыми моментами для успешной десериализации XDTO-объектов являются:

  1. Корректная настройка веб-сервиса: Включение всех необходимых XDTO-пакетов и использование правильных URI пространств имен.

  2. Перезапуск веб-сервера: После любых изменений в конфигурации, затрагивающих веб-сервисы или XDTO.

  3. Точное соответствие XML-запроса XDTO-схеме: Особенно критично соблюдение порядка тегов и чувствительность к регистру имен элементов.

  4. Правильная обработка необязательных и пустых полей: Использование minOccurs="0" для пропуска тегов и xsi:nil="true" для явного указания отсутствия значения.

Внимательное изучение документации, тщательная проверка XML-запроса и использование инструментов отладки помогут нам быстро выявить и устранить подобные проблемы, обеспечивая надежный и корректный обмен данными через веб-сервисы 1С.

← На главную