Описание
Для уменьшения количества кода, требуемого для подключения к любым JSON веб-сервисам, мною были написаны классы отправляющие JSON запросы. Один из них называется RequestSender, и используется для подключения к веб-сервисам не требующим аутентификации OAuth. Второй называется RequestSender_OAuth, — это наследник RequestSender, который используется с теми веб-сервисами, где необходима аутентификация OAuth, в том числе и с веб-сервисами D365O.
Подготовительный этап
Принцип работы
Для начала работы с классами RequestSender и RequestSender_OAuth, нужно создать объект одного из этих классов. В случае с RequestSender, в конструктор необходимо передать базовый URL ресурса, на котором развернут веб-сервис. В случае с RequestSender_OAuth, конструктор вызывается без аргументов, а базовый URL берется из AuthenticationUtility Microsoft.
Классы RequestSender и RequestSender_OAuth содержат два публичных метода. Рассмотрим функционал и переменные каждого из них.
Метод отправляет запрос типа GET на веб сервис.
При вызове нужно указать на месте дженерика <OutputContract> класс контракта, в который будет преобразована полученая в ответе JSON строка.
Также в качестве аргумента нужно передать requestMessageText – строку текста запроса. Содержит относительный URL запроса и, характерные для GET запросов, значения переменных запроса, передаваемые прямо в строке URL.
Метод отправляет запрос типа POST на веб сервис.
При вызове нужно указать на месте дженериков <InputContract> и <OutputContract> классы контрактов, — один будет отправлен на вход вебсервиса, а во второй будет преобразована полученая в ответе JSON строка.
Также в качестве параметров нужно передать следующее:
Для этой переменной задается базовый адрес запроса.
Если вебсервис требует OAuth аутентификации, как в случае с сервисами D365O, к переменной клиента добавляется хедер аутентификации, как один из параметров массива DefaultRequestHeaders.
Как видно, для генерации хедера используется метод из AuthenticationUtility Microsoft. Если введенные в классе ClientConfiguration логин и пароль неверные, или же если пользователь не имеет доступа к приложению Azure, ID которого указан в том же классе, программа прекратит работу.
Далее создается переменная класса HttpRequestMessage, отвечающая за запрос, отправляемый клиентом. При создании переменной запроса, нужно указать тип запроса и относительный адрес метода веб-сервиса.
Например для запроса типа GET:
В случае запроса типа POST, в теле запроса должны быть переданы данные в формате JSON. Для этого производится сериализация класса контракта, содержащего эти данные.
Далее с помощью переменной клиента вызывается метод веб-сервиса, на который настроен запрос. При этом вызов метода делается в блоке try-catch, что предотвращает падение программы в случае ошибки подключения к веб-сервису по указаному URL.
Полученный результат содержит в себе, в частности, статус выполнения (успешно/неуспешно), а также выходные данные веб-сервиса, или сообщение с текстом ошибки, если что-то пошло не так. Для обработки результата проверяется статус выполнения запроса, после чего считывается его содержимое. Как в случае с получением выходных данных, так и в случае с получением текста ошибки, эта информация получается в виде строки JSON.
Для преобразования полученной строки JSON в объекты контрактов используется класс JsonConvert.
Как видно, в классе JsonConvert вызывается метод DeserializeObject. При этом передается дженерик класс (или примитивный тип), в который необходимо преобразовать строку JSON, и два аргумента, — строка JSON и параметры преобразования. В параметрах преобразования, в том числе, можно выбрать реакцию на несоответствие дженерик класса со структурой строки JSON. Если, как в примере, параметр MissingMemberHandling равен MissingMemberHandling.Error, метод бросит ошибку при несоответствии структур.
Десериализацию строки JSON лучше производить в блоке try-catch.