Описание
По сравнению с AX2012, в D365O, была добавлена возможность развертывания JSON веб-сервисов, выполняющих заданную программистом логику. Эти веб-сервисы могут принимать от подключенных к ним клиентов некоторые данные, после чего выполнить работу с таблицами D365O и вернуть результат.
Логика таких веб-сервисов написана на языке X++, но клиентские программы, подлючающиеся к веб-сервису, не зависят от языка программирования, так как они видят только генерируемые при развертывании JSON веб-сервиса страницы, на которых в формате JSON, представляющем собой строку с парами ключ-значение, дается полное описание всех доступных методов веб-сервиса и их переменных.
JSON веб-сервисы имеют две разновидности – одни из них работают с POST запросами, а другие – с GET. POST запросы передают данные в своем теле, храня их в специальной переменной. GET запросы передают данные в строке URL. Развернутые в D365O JSON веб-сервисы работают с POST запросами.
Для вызова JSON веб-сервисов, в клиентской программе нужно подключиться к адресу URL нужного метода веб-сервиса, передав в него данные или в теле запроса, или в самой URL, в зависимости от типа запроса. При этом веб-сервис возвращает данные в формате JSON, который, так как он является строкой, необходимо преобразовать в объекты (десериализовать).
В сравнении с SOAP веб-сервисами, описанными в статье «Руководство по подключению к SOAP веб-сервисам Microsoft Dynamics 365 for Operations» , JSON работает быстрее, так как JSON формат описывает данные компактнее чем XML формат, используемый в SOAP.
Вызов веб-сервиса D365O из Desktop приложения
Подготовительный этап
Основной код
При использовании вспомогательного проекта JsonRequestSender, вызов JSON веб-сервисов сводится к одной команде. Для этого сначала нужно создать объект класса RequestSender или RequestSender_OAuth.
Так как в вебсервисах D365O используется аутентификация OAuth, нужен класс JsonRequestSender_OAuth.
Далее, так как JSON вебсервисы D365O используют POST запросы, отправляем POST запрос.
В метод sendPOSTRequest() передаются два дженерик класса и два аргумента.
Дженерик классы определяют то, объекты какого класса должны использоваться в качестве входных и выходных контрактов с данными в веб-сервисе.
Первый из аргументов , — это относительный адрес вызываемого метода веб-сервиса в ресурсе. В данном случае вызывается метод createInventJournal веб-сервиса InventJourMovementGeneratorService из группы веб-сервисов InventJourMovementGeneratorServiceGroup, а все JSON веб-сервисы D365O лежат по адресу api/services. Такая структура относительного адреса характерна для D365O, но может быть другой для JSON веб-сервисов развернутых не в D365O. В некоторых случаях относительный адрес может даже быть пустым, если базовый адрес ресурса и есть ссылка на веб-сервис.
Второй аргумент, — это объект контракта с данными, передаваемый в теле POST запроса.
Рассмотрим сигнатуру вызываемого метода веб-сервиса:
Как видно, для вызова метода нужно 2 аргумента:
Оба этих аргумента должны быть переданы внутри единого объекта контракта в теле POST запроса, поэтому необходимо написать класс JSON контракта:
При этом класс ServiceInputContract, используемый в JsonInputContract представляет собой копию структуры класса InventJourMovementGeneratorServiceInputContract из D365O.
На выходе метода вебсервиса со стороны D365O возвращается класс контракта InventJourMovementGeneratorServiceOutputContract. Как было видно раньше в примере POST запроса, при вызове вебсервиса результат сохраняется в объект контракта JsonOutputContract, который представляет собой копию InventJourMovementGeneratorServiceOutputContract из D365O.
При использовании пакета System.Runtime.Serialization на классы контрактов и их переменные можно добавить аттрибуты [DataContract] и [DataMember], как показано в статье «Добавление пакета System.Runtime.Serialization», для изменения названий переменных по сравнению с их названиями со стороны сервера.
Если входной контракт или вложенные в него контракты клиента не имеют каких-либо компонентов из структуры контрактов сервера, пропущенные значения будут пустыми на сервере.
Если выходной контракт или вложенные в него контракты клиента не имеют каких-либо компонентов из структуры контрактов сервера, будет выдаваться ошибка, так как вспомогательный класс RequestSender настроен на проверку структуры при преобразовании возвращаемой JSON строки в класс контракта. При желании настройку в RequestSender можно поменять, и тогда на выходе заполнятся только те переменные в контракте клиента, для которых есть переменные в контракте сервера.
Пример
В качестве примера приведено подключение к сервису для создания записи в складском журнале перемещений из статьи «Развертывание SOAP и JSON веб-сервисов в D365O» с помощью приложения Windows forms.