Почему не создается объект XDTO для простого типа (число или дата) и как правильно передавать параметры в веб-сервис?

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

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

Анализ типичной ошибки при использовании ФабрикаXDTO.Создать()

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


// Ошибка здесь:
ТипЧисло = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "decimal");
ОбъектXDTOЧисло = ФабрикаXDTO.Создать(ТипЧисло, "decimal"); 

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

Интересно, что для типа string аналогичный код может сработать "случайно":


ТипСтрока = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "string");
ОбъектXDTOСтрока = ФабрикаXDTO.Создать(ТипСтрока, "string"); 

В данном случае ошибки не будет, но в созданный объект запишется значение "string", а не та переменная, которую вы, возможно, планировали передать. Это вводит разработчиков в заблуждение, заставляя думать, что метод Создать() работает именно так.

Решение №1: Автоматическое сопоставление (Mapping) типов

Самый важный аспект при работе с Web-сервисами в 1С заключается в том, что простые типы данных создавать через фабрику XDTO не нужно. Платформа обладает встроенным механизмом автоматического сопоставления типов 1С (примитивных типов) и типов XSD (XML Schema Definition).

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


// Предположим, у нас есть подключение к веб-сервису (WSПрокси)
ПараметрЧисло = 150.50;
ПараметрДата  = ТекущаяДата();
ПараметрСтрока = "Тестовая строка";

// Просто вызываем метод, передавая обычные значения
Результат = Прокси.ИмяМетодаСервиса(ПараметрЧисло, ПараметрСтрока, ПараметрДата);

Платформа 1С самостоятельно выполнит следующие преобразования при формировании SOAP-пакета:

Решение №2: Правильное использование ФабрикаXDTO.Создать()

Если в силу специфики архитектуры (например, при использовании типа anyType) вам все же необходимо создать объект XDTO для простого типа вручную, это нужно делать, передавая в качестве второго параметра реальное значение нужного типа, а не его название:


// Правильное создание простого типа через фабрику
ТипDecimal = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "decimal");
МоеЧислоXDTO = ФабрикаXDTO.Создать(ТипDecimal, 123.45); // Передаем число, а не строку "decimal"

ТипDate = ФабрикаXDTO.Тип("http://www.w3.org/2001/XMLSchema", "date");
МояДатаXDTO = ФабрикаXDTO.Создать(ТипDate, ТекущаяДата()); // Передаем дату

В результате вы получите объект типа XDTODataValue. Важно понимать различие:

  1. XDTODataObject — это сложный объект (структура), у него есть свойства, к которым можно обращаться через точку.
  2. XDTODataValue — это простое значение, у него нет вложенных свойств, кроме системного свойства Значение.

Когда действительно необходимо использовать Фабрику XDTO?

Разберем ситуации, когда без явного использования ФабрикаXDTO не обойтись:

Использование Сериализатора XDTO

Проанализируем еще один полезный инструмент — СериализаторXDTO. Он позволяет быстро преобразовывать объекты 1С в объекты XDTO и наоборот. Это особенно удобно для типов, которые имеют прямое соответствие в метаданных.


// Пример преобразования ссылки в XDTO
МояСсылка = Справочники.Номенклатура.НайтиПоКоду("001");
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(МояСсылка);

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

← На главную