При разработке интеграций на платформе 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. Давайте выясним, почему это происходит и как это исправить.
Тип {http://www.w3.org/2001/XMLSchema}anyType является базовым типом для всех XDTO-объектов. Когда платформа 1С получает XML-данные, предназначенные для параметра веб-сервиса, она пытается десериализовать их в соответствии с ожидаемым XDTO-типом. Если процесс сопоставления входящего XML со схемой XDTO завершается неудачей, 1С не может распознать структуру как конкретный тип и по умолчанию присваивает ей anyType. Это сигнал о том, что между тем, что мы отправляем, и тем, что ожидает 1С, есть расхождение.
Мы рассмотрим несколько ключевых областей, где могут скрываться причины этой проблемы:
Настройки веб-сервиса и окружения: Убедимся, что все необходимые конфигурации выполнены корректно, и изменения вступили в силу.
Детальный разбор XML-запроса и XDTO-схемы: Проверим, насколько точно структура и содержимое нашего XML-запроса соответствуют описанию XDTO-типа в 1С. Это, как мы увидим далее, является наиболее частой причиной.
Обработка необязательных и пустых полей: Разберем, как правильно передавать пустые значения или пропускать необязательные поля в XML.
Прежде чем углубляться в структуру XML, давайте убедимся, что базовая настройка веб-сервиса выполнена правильно. Некоторые проблемы могут быть вызваны простыми недочетами в конфигурации или отсутствием ее обновления.
После любых изменений в конфигурации 1С, касающихся XDTO-пакетов, веб-сервисов или их методов, критически важно перезапустить веб-сервер, на котором опубликована информационная база. Это может быть IIS или Apache. Почему это так важно? Платформа 1С кэширует WSDL-описания и XDTO-схемы веб-сервисов. Если мы внесли изменения (например, добавили новое свойство в XDTO-тип или изменили его структуру), но не перезапустили веб-сервер, он будет продолжать использовать старые, кэшированные описания. В результате, даже если в конфигурации 1С все правильно, веб-сервер будет "ожидать" старую структуру, и входящий запрос с новой структурой не сможет быть корректно десериализован.
Пользователь в своем случае уже попробовал перезапуск веб-сервера, но это не помогло. Это указывает на то, что проблема лежит глубже, скорее всего, в несоответствии самого XML или схеме XDTO, но этот шаг всегда должен быть первым в списке проверок.
Необходимо убедиться, что в свойствах нашего веб-сервиса, на вкладке "Прочее" (или аналогичной, в зависимости от версии платформы), указаны все необходимые XDTO-пакеты, которые используются в его операциях. Если XDTO-пакет "artasks_XDTO" не указан в этом списке, платформа 1С может просто не "знать" о существовании типа TaskData из этого пакета при обработке входящих запросов. В таком случае, она не сможет найти соответствующую схему для десериализации и, по умолчанию, использует anyType.
Для проверки выполните следующие шаги:
Откройте конфигуратор 1С.
Перейдите в ветку "Веб-сервисы" (или "HTTP-сервисы", в зависимости от типа используемого сервиса).
Откройте свойства вашего веб-сервиса (например, "ws.ar-mobile-tasks").
Найдите вкладку "Прочее" (или похожую, например, "XDTO-пакеты").
Убедитесь, что пакет "artasks_XDTO" присутствует в списке используемых пакетов.
Если пакет отсутствует, добавьте его, сохраните конфигурацию и обязательно перезапустите веб-сервер.
Пространства имен в 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-схемой. 1С является достаточно строгой в отношении соответствия входящих данных их описанию. Давайте рассмотрим эти аспекты подробнее.
Этот пункт был одним из решающих для автора проблемы. Для XDTO-типов, определенные как "последовательные" (sequence в XSD), порядок элементов в XML-запросе является критически важным. Если в нашем XDTO-пакете тип TaskData определен, например, со следующей последовательностью элементов:
orgCodedbIDauthorТо и в XML-запросе эти элементы должны идти именно в такой последовательности. Если мы поменяем их местами, например, отправим до , 1С не сможет правильно распознать структуру объекта. Несмотря на то, что в некоторых XML-схемах порядок элементов может быть нестрогим (например, если используется all или choice в XSD), по умолчанию многие инструменты и, в частности, 1С, ожидают последовательное соответствие.
Чтобы проверить порядок тегов, необходимо открыть XDTO-пакет "artasks_XDTO" в конфигураторе 1С, выбрать тип TaskData и посмотреть на порядок свойств, указанных для этого типа. Убедитесь, что ваш XML-запрос точно воспроизводит этот порядок.
Вторым, не менее важным аспектом, ставшим причиной проблемы, является строгая чувствительность XML к регистру символов. Это означает, что для XML и — это совершенно разные элементы. Аналогично, если в XDTO-схеме свойство называется orgCode (с маленькой буквы), а в XML-запросе мы передадим его как (с большой буквы), 1С не сможет сопоставить этот элемент с ожидаемым свойством. Это одна из самых частых ошибок, приводящих к некорректной десериализации.
Внимательно просмотрите ваш XML-запрос и убедитесь, что каждое имя тега и атрибута в XML полностью соответствует имени соответствующего свойства в XDTO-схеме, включая регистр. Это касается как корневого элемента параметра (например, , где TaskData должно совпадать с именем параметра функции), так и всех вложенных элементов (, и т.д.).
Давайте еще раз взглянем на предоставленный XML-запрос с учетом этих правил:
33333
1668058686
07bb51fc-a773-489a-91e6-8b03712a9120
Здесь мы видим, что корневой элемент параметра TaskData находится внутри элемента (это имя операции веб-сервиса). Внутри находятся элементы с префиксом art: (, и т.д.), которые соответствуют полям нашего XDTO-объекта.
Для успешной десериализации:
Имя элемента TaskData (внутри ) должно точно соответствовать имени параметра функции SetTaskData(TaskData).
Пространство имен artasks_XDTO (присвоенное префиксу art:) должно точно совпадать с URI XDTO-пакета в 1С.
Порядок всех дочерних элементов , , и т.д. должен точно соответствовать порядку свойств в описании XDTO-типа TaskData в 1С.
Регистр каждого имени тега (например, orgCode, dbID, author) должен быть идентичен регистру соответствующих свойств в XDTO-типе TaskData.
Любое отклонение в этих пунктах приведет к тому, что 1С не сможет найти подходящую схему и десериализует объект как anyType.
Автор проблемы также задал важный вопрос о том, можно ли пропускать поля в XML, если в XDTO указано, что поле может быть пустым. Давайте разберем этот нюанс, так как он часто вызывает путаницу.
Чтобы элемент можно было полностью пропустить (не указывать его в XML-запросе), в XDTO-схеме для соответствующего свойства должно быть установлено минимальное количество вхождений (minOccurs) в 0. По умолчанию, если minOccurs не указано, оно равно 1, что означает, что элемент является обязательным и должен присутствовать в XML. Если элемент обязателен, но отсутствует в XML, это может привести к ошибке десериализации или, в лучшем случае, к получению anyType.
Если свойство в XDTO имеет minOccurs="0", мы можем просто не включать соответствующий тег в наш XML-запрос, и 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С такое значение будет интерпретировано как Неопределено.
Обычный пустой тег: Если мы хотим передать пустую строку для строкового поля или 0 для числового, мы можем использовать обычный пустой тег:
или
В 1С это будет интерпретировано как пустая строка для строковых типов, 0 для числовых, Ложь для булевых и т.д., в зависимости от типа свойства. Такой подход не требует атрибута xsi:nil="true" и используется, когда мы хотим передать именно "пустое" значение, а не его отсутствие (Неопределено).
Таким образом, важно различать: хотим ли мы пропустить элемент полностью (для чего нужно minOccurs="0" в схеме) или же хотим передать "пустое" или "неопределенное" значение (для чего используются пустые теги или xsi:nil="true" в зависимости от желаемого результата и настроек nillable в схеме).
Для диагностики подобных проблем с веб-сервисами и XDTO крайне полезно использовать специализированные инструменты:
SoapUI: Это мощный инструмент для тестирования SOAP- и REST-сервисов. Он позволяет отправлять запросы, просматривать ответы, валидировать XML по WSDL-схемам. С его помощью мы можем убедиться, что формируемый клиентский запрос соответствует ожиданиям сервера, а также увидеть полный текст запроса и ответа.
Отладчик 1С: Подключите отладчик к веб-сервису 1С и установите точку останова в начале функции SetTaskData. Это позволит нам пошагово выполнить код и проверить значение TaskData.Тип(), а также просмотреть структуру полученного объекта.
Логирование веб-сервера: Если веб-сервис опубликован на IIS или Apache, мы можем настроить логирование входящих HTTP-запросов. Это позволит нам увидеть полный текст XML-запроса, который действительно дошел до сервера, и сравнить его с тем, что мы отправляли, выявляя возможные искажения или ошибки передачи.
Проблема получения anyType вместо ожидаемого XDTO-типа в параметре функции веб-сервиса 1С является достаточно распространенной, но, как мы выяснили, имеет четкие причины и решения. Ключевыми моментами для успешной десериализации XDTO-объектов являются:
Корректная настройка веб-сервиса: Включение всех необходимых XDTO-пакетов и использование правильных URI пространств имен.
Перезапуск веб-сервера: После любых изменений в конфигурации, затрагивающих веб-сервисы или XDTO.
Точное соответствие XML-запроса XDTO-схеме: Особенно критично соблюдение порядка тегов и чувствительность к регистру имен элементов.
Правильная обработка необязательных и пустых полей: Использование minOccurs="0" для пропуска тегов и xsi:nil="true" для явного указания отсутствия значения.
Внимательное изучение документации, тщательная проверка XML-запроса и использование инструментов отладки помогут нам быстро выявить и устранить подобные проблемы, обеспечивая надежный и корректный обмен данными через веб-сервисы 1С.