понедельник, 12 ноября 2012 г.

1С:Предприятие 8. Веб-сервисы. XDTO


Содержание статей: 1С:Предприятие 8. Веб-сервисы
Предыдущая статья: 1С:Предприятие 8. Веб-сервисы. Реализация собственного веб-сервиса

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

XDTO (XML Data Transfer Objects) это механизм позволяющий создавать модель данных и переводить ее в формат XML. Простыми словами, вы можете сделать модель документа поступления товаров и услуг через XDTO и выгрузить любой документ в XML файл, не работая с файлом напрямую.
Этот механизм применяется при обмене файлами XML и при работе с типами в веб-сервисах.
Давайте попробуем разобраться с XDTO. У нас уже есть конфигурация с веб-сервисом и веб операцией Plus2(). Пусть теперь эта операция будет возвращать сообщения о ошибках. Например, если входящий параметр функции меньше нуля, мы будем выдавать ошибку "Error", в остальных случаях будем выдавать "ОК". То есть теперь функция Plus2 будет возвращать структуру:

  1. Результат - число - результат выполнения сложения. 0 если есть ошибка;
  2. Ошибка - строка - "Ok" или "Передано отрицательное значение".
Для создания такой структуры мы будем использовать тип ОбъектXDTO, так как он может описать сложную структуру с несколькими реквизитами различных типов. Помимо ОбъектXDTO существует тип ЗначениеXDTO, но данный тип не позволяет описывать сложные структуры, потому использовать мы его не можем.

Для этого нам надо:

  1. Создать модель XDTO для нашей структуры;
  2. В модуле веб-сервиса создать ОбъектXDTO для для того что бы возвратить как результат функции.
Приступим. Откроем базу в режиме конфигурирования. Найдем в дереве метаданных XDTO и создадим новый пакет XDTO.

XDTO

Откроется окно свойств, назовем этот пакет "ТипыВебСервиса". В свойство "URI пространства имен" укажем "http://codenotes-1c.blogspot.com". Как я уже писал в статье 1С:Предприятие 8. Веб-сервисы. Реализация собственного веб-сервиса нет особого значения что вы укажете в этом поле и даже не особо важно (для 1С) что эта строка будет ссылкой URI. 

После этого пакет можно открыть, щелкнув в дереве метаданных по пакету "ТипыВебСервиса" и в новом окне добавим "Тип объекта".

ОбъектXDTO

Дадим ему имя "РезультатОперации", остальные свойства можно не менять. 

ОбъектXDTO

У объекта создадим свойство. Для этого нажмем на него правой кнопкой и выберем "Добавить - Свойство".

Свойства ОбъектXDTO

И в окне свойств заполним его свойства. Укажем имя "Результат" и тип int из пространства имен http://www.w3.org/2001/XMLSchema как показано на рисунке.

Реквизиты ОбъектXDTO

И создадим второе свойство "Ошибка" как на картинке ниже.

Реквизиты Объект XDTO

На этом завершено создание пакета XDTO. Теперь можно приступить к написанию кода обработки ошибки и возврата результата веб-операции.

У нашего веб-сервиса WebService в свойство "Пакет XDTO" укажем только что созданный пакет. Иначе не сможем указать у веб-операции Plus2 тип "РезультатОперации".

Веб сервис ПакетXDTO

Откроем свойства веб-операции Plus2 в поле "Тип возвращаемого значения" выберем тип "РезультатОперации" из пакета с пространства имен "http://codenotes-1c.blogspot.com" как на рисунке.

ОбъектXDTO

Теперь функция Plus2 будет возвращать не число, а структуру с двумя полями "Результат" и "Ошибка". Давайте откроем модуль веб-сервиса. Так как созданная нами структура не является стандартным типом то необходимо создать переменную типа "РезультатОперации", конечно на самом деле это будет ОбъектXDTO. 

ТипXDTOРезультатОперации = ФабрикаXDTO.Тип("http://codenotes-1c.blogspot.com", "РезультатОперации");

Этой строкой мы с помощью Фабрики XDTO в конфигурации создали ТипОбъектаXDTO, указав пространство имен пакета и имя типа.

РезультатОперации = ФабрикаXDTO.Создать(ТипXDTOРезультатОперации);

Эта строка создает уже сам ОбъектXDTO, с которым можно уже будет работать привычным способом (обращение к реквизитам через точку). Далее мы перепишем код, добавив проверку на отрицательные значения, и код веб-операции будет выглядеть так:


Функция Plus2(Параметр)
ТипXDTOРезультатОперации = ФабрикаXDTO.Тип("http://codenotes-1c.blogspot.com", "РезультатОперации");
РезультатОперации = ФабрикаXDTO.Создать(ТипXDTOРезультатОперации);
Если Параметр < 0 Тогда 
РезультатОперации.Результат = 0;
РезультатОперации.Ошибка = "Передано отрицательное значение";
Иначе
РезультатОперации.Результат = Параметр+2;
РезультатОперации.Ошибка = "Ok";
КонецЕсли;
Возврат РезультатОперации;
КонецФункции


Если вызвать эту операцию с отрицательным значением то получим следующий результат:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header/>
   <soap:Body>
      <m:Plus2Response xmlns:m="www.URI.com">
         <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <Результат xmlns="http://codenotes-1c.blogspot.com">0</Результат>
            <Ошибка xmlns="http://codenotes-1c.blogspot.com">Передано отрицательное значение</Ошибка>
         </m:return>
      </m:Plus2Response>
   </soap:Body>
</soap:Envelope>

О том как вызвать операцию веб-сервиса и просмотреть результат вы можете прочитать в статье 1С:Предприятие 8. Веб-сервисы. Публикация и тестирование


Вы видите что в результате сообщение веб-операции содержит два поля - Результат и Ошибка.
В данном примере описана работа с ОбъектомXDTO. Как я уже говорил, его отличие от ЗначениеXDTO в том, что ЗначениеXDTO не может описывать структурированные типы, вы не сможете, используя ЗначениеXDTO создать тип передающий какой либо документ или справочник. Но! ЗначениеXDTO имеет большие возможности по описанию ограничений примитивных типов и нашу задачу с проверкой на отрицательное значение параметра можно было решить более изящно. Если создать в пакете XDTO ТипЗначения "ПоложительноеЧисло" и указать его минимум,

ЗначениеXDTO

то этот тип можно использовать как тип входного параметра:

Свойства параметра веб-операции

Теперь при вызове веб-операции с отрицательным значением в ответ мы получим сообщение об ошибке:


<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header/>
   <soap:Body>
      <soap:Fault>
         <soap:Code>
            <soap:Value>soap:Sender</soap:Value>
         </soap:Code>
         <soap:Reason>
            <soap:Text xml:lang="ru_RU">Неизвестная ошибка. Ошибка проверки данных XDTO:
Значение: '-2' не соответствует простому типу: {http://codenotes-1c.blogspot.com}ПоложительноеЧисло
Несоответствие фасету MinInclusive = '0'
по причине:
Ошибка проверки данных XDTO:
Значение: '-2' не соответствует простому типу: {http://codenotes-1c.blogspot.com}ПоложительноеЧисло
Несоответствие фасету MinInclusive = '0'</soap:Text>
         </soap:Reason>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

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

8 комментариев:

  1. Отличная статья! Спасибо!
    Остался только вопорс: в начале статьи "договорились", что будем проверять превышает ли переданный параметр значение 100, а вот в конце статьи обошлись просто проверкой на отрицательное значение. (честно говоря, это даже показалось мне более полезным). Может имеет смысл немного поправить первоначальную задачу?

    ОтветитьУдалить
    Ответы
    1. Спасибо за замечание, задачу поправил. Вообще, эту задачу проверки на допустимые значения лучше решать через фасеты. Постараюсь об этом позже написать.

      Удалить
    2. Спасибо за быструю реакцию на предложение по устранению неточности в статье!
      По ходу разбирательства обнаружил ещё одну неточность. В начале "договорились", что в структуре ОТВЕТ может принимать два значения "Ок" или "Error". Не смотря на это функция Plus2(Параметр) возвращает в структуре ОТВЕТ = "" или "Передано отрицательное значение". Может лучше немного поправить, чтоб ОТВЕТ был = "Ок" или "Передано отрицательное значение" в начале статьи и в самой функции?

      Удалить
    3. Спасибо за замечание. Поправил как вы предложили.

      Удалить
  2. Эх... рассказал бы кто-нибудь как со свойствами пакета работать. Как их считывать, записывать в файл? Везде только про Типы значений и Типы объектов рассказано.

    ОтветитьУдалить
    Ответы
    1. Спешл фор ю. Конфа с примером записи через XDTO в файл. Там кода не много, думаю объяснения не нужны.
      https://yadi.sk/d/m_hvQmlOxEaF9

      На всякий случай если база будет не доступна выкладываю код сюда, но без самого пакета:

      Запрос = Новый Запрос;
      Запрос.Текст =
      "ВЫБРАТЬ
      | Контрагенты.Наименование,
      | Контрагенты.ИНН
      |ИЗ
      | Справочник.Контрагенты КАК Контрагенты";

      РезультатЗапроса = Запрос.Выполнить();

      ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
      ПространствоИмен = "http://www.sample-package.org";

      ТипXDTOМассив = ФабрикаXDTO.Тип(ПространствоИмен, "Массив");
      ОбъектXDTOМассив = ФабрикаXDTO.Создать(ТипXDTOМассив);

      Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
      ТипXDTO = ФабрикаXDTO.Тип(ПространствоИмен, "Контрагент");
      ОбъектXDTO = ФабрикаXDTO.Создать(ТипXDTO);
      ОбъектXDTO.Наименование = ВыборкаДетальныеЗаписи.Наименование;
      ОбъектXDTO.ИНН = ВыборкаДетальныеЗаписи.Наименование;
      ОбъектXDTOМассив.Контрагент.Добавить(ОбъектXDTO);
      КонецЦикла;

      ЗаписьXML = Новый ЗаписьXML;
      ЗаписьXML.ОткрытьФайл("E:\1.txt");
      ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектXDTOМассив, ,ПространствоИмен);
      ЗаписьXML.Закрыть();

      Удалить
  3. Анонимный08 июня, 2020 15:27

    Мистер Бенджамин сделал все возможное, чтобы помочь мне с моим кредитом, который я использовал, чтобы расширить мой аптечный бизнес. Они были дружелюбны, профессиональны и абсолютно самоотверженны. Я рекомендую всем, кто ищет кредит, связаться с нами. lfdsloans@outlook.com.WhatsApp ... + 19893943740.

    ОтветитьУдалить
  4. Всем привет, я Хесус Маккинни из Техаса, и я просто хочу сказать очень громкое спасибо финансовым кредитным службам от Бенджамина Ли за их искренность, открытость, прозрачность, правдивость, любовь и поддержку во время и после получения от них ссуд. Я через многое прошел, и время не позволяет мне рассказать обо всем, через что я прошел в Интернете, в гостях или в получении ссуды, чтобы получить дом здесь, в США, но Бог ответил на мои молитвы через поддержку и любовь со стороны Бенджамина Ли, который обнял меня и понял меня, несмотря на мои первоначальные сомнения и несерьезность, и с его добрым сердцем и любовью, теперь я являюсь владельцем дома благодаря его ссудным фондам с процентной ставкой 2%, и я клянусь распространить эту новость, а также рассказать миру, что все еще есть настоящие и несколько хороших онлайн-кредитных компаний, которые могут помочь, а также оживить сухую кость. Не упустите возможность послушать и прочитать это свидетельство, потому что это настоящий жизненный опыт, и любой, кто нуждается в таком изменении, не должен колебаться или сомневаться это потому, что я доказал и клянусь Богом на Небесах, что эта история реальна, а также история моего опыта с ними.
    Свяжитесь с ними сегодня. Текст в WhatsApp: (+1 989-394-3740) Электронная почта: 247officedept@gmail.com

    ОтветитьУдалить