|
![]() |
#1 |
Administrator
|
D365FO: Использование веб-сервиса через JSON
Для JSON структура построения кода несколько иная. Нам необходимо подготовить строку текста в некотором формате, затем вызвать сервис, передав ему эту строку, после чего получить ответ также в виде строки и разобрать полученную строку.
Тем не менее, нам также нужно создать проект на C# типа Console Application (или любого типа, который может быть запущен напрямую пользователем) Процедура аутенфикации такая же, поэтому также необходимо добавлять в проект ссылку на библиотеку Microsoft.IdentityModel.Clients.ActiveDirectory путем выполнения команды Цитата:
Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
Строку можно готовить (сериализовать) и разбирать (десериализовать) как "ручками", так и при помощи библиотеки Newtonsoft.Json, которую аналогичным способом (как и Microsoft.IdentityModel.Clients.ActiveDirectory) можно добавить в Package Manager Console путем выполнения команды Цитата:
Install-Package Newtonsoft.Json
ClientConfiguration.cs (с правками по параметрам авторизации) OAuthHelper.cs (без правок) А теперь начинаются различия. Для начала нам понадобится класс JsonUtil, который будет генерировать нам URL-адрес, добавляя в него группу сервисов, сам сервис и операции сервиса. X++: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tutorial_ConsumeServiceJSON { public class JsonUtil { public const string OAuthHeader = "Authorization"; public static string GetJsonServiceGroupURL(string aosUriString, string serviceGroupName) { var serviceUriStringTemplate = "{0}/api/services/{1}"; var serviceUriString = string.Format(serviceUriStringTemplate, aosUriString.TrimEnd('/'), serviceGroupName); return serviceUriString; } public static string GetJsonServiceNameURL(string aosUriString, string serviceGroupName, string serviceName) { var serviceUriStringTemplate = "{0}/{1}"; var serviceUriString = string.Format(serviceUriStringTemplate, GetJsonServiceGroupURL(aosUriString, serviceGroupName), serviceName); return serviceUriString; } public static string GetJsonOperationURL(string aosUriString, string serviceGroupName, string serviceName, string functionName) { var serviceUriStringTemplate = "{0}/{1}"; var serviceUriString = string.Format(serviceUriStringTemplate, GetJsonServiceNameURL(aosUriString, serviceGroupName, serviceName), functionName); return serviceUriString; } } } 1. Описать класс-контракт, описанный на X++, т.к. в отличие от SOAP - здесь не передаются объекты, а значит для получения карточки клиента - нам потребуется повторное описание полей карточки. Это делается так: X++: public class Tutorial_CustServiceContract { public string parmCustAccount { get; set; } [JsonProperty("parmCustAccountName")] public string custAccountName { get; set; } public string parmCustGroupId { get; set; } } 2. Библиотека Newtonsoft.Json умеет сериализовать / десериализовать только классы, поэтому если нам надо передать в сервис обычное значение (например, код клиента), то чтобы вручную не формировать строку JSON - нужно создать классы, состоящие из одной этой переменной: X++: public class ParmCustAccount { [JsonProperty("_custAccount")] public string custAccount { get; set; } } public class ParmCustGroupId { [JsonProperty("_custGroupId")] public string custGroupId { get; set; } } В итоге у меня получилось 2 класса: JsonServices, который вызывает веб-сервис X++: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.IO; using Newtonsoft.Json; using AuthenticationUtility; namespace Tutorial_ConsumeServiceJSON { public class Tutorial_CustServiceContract { public string parmCustAccount { get; set; } [JsonProperty("parmCustAccountName")] public string custAccountName { get; set; } public string parmCustGroupId { get; set; } } public class ParmCustAccount { [JsonProperty("_custAccount")] public string custAccount { get; set; } } public class ParmCustGroupId { [JsonProperty("_custGroupId")] public string custGroupId { get; set; } } public class JsonServices { public const string serviceGroupName = "Tutorial_CustServiceGroup"; public const string serviceName = "Tutorial_CustService"; public const string getCustDetailName = "getCustDetail"; public const string getCustListOfGroupName = "getCustListOfGroup"; string aosUriString; string bearerKey; [JsonProperty("return")] public Tutorial_CustServiceContract[] serviceContracts { get; set; } [JsonProperty("return")] public Tutorial_CustServiceContract serviceContract { get; set; } public JsonServices() { aosUriString = ClientConfiguration.Default.ActiveDirectoryResource; bearerKey = OAuthHelper.GetAuthenticationHeader(true); } private HttpWebRequest CreateRequest(string _address) { HttpWebRequest webRequest; webRequest = (HttpWebRequest)HttpWebRequest.Create(_address); webRequest.Method = "POST"; // the request will be empty. webRequest.ContentLength = 0; webRequest.Headers.Set(JsonUtil.OAuthHeader, bearerKey); return webRequest; } private string ReadJsonResponse(HttpWebRequest _request) { string jsonString; using (HttpWebResponse webResponse = (HttpWebResponse)_request.GetResponse()) { using (Stream stream = webResponse.GetResponseStream()) { using (StreamReader reader = new StreamReader(stream)) { jsonString = reader.ReadToEnd(); } } } return jsonString; } public Tutorial_CustServiceContract getCustDetail(string _custAccount) { string operationURL = JsonUtil.GetJsonOperationURL(aosUriString, serviceGroupName, serviceName, getCustDetailName); ParmCustAccount parmCustAccount = new ParmCustAccount(); parmCustAccount.custAccount = _custAccount; string jsonCustAccount = JsonConvert.SerializeObject(parmCustAccount); HttpWebRequest webRequest; webRequest = CreateRequest(operationURL); webRequest.SendChunked = true; using (Stream stream = webRequest.GetRequestStream()) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(jsonCustAccount); writer.Flush(); } } string jsonResponse = ReadJsonResponse(webRequest); serviceContract = JsonConvert.DeserializeObject<Tutorial_CustServiceContract>(jsonResponse); return serviceContract; } public Tutorial_CustServiceContract[] getCustListOfGroup(string _custGroupId) { string operationURL = JsonUtil.GetJsonOperationURL(aosUriString, serviceGroupName, serviceName, getCustListOfGroupName); ParmCustGroupId parmCustGroupId = new ParmCustGroupId(); parmCustGroupId.custGroupId = _custGroupId; string jsonCustGroupId = JsonConvert.SerializeObject(parmCustGroupId); HttpWebRequest webRequest; webRequest = CreateRequest(operationURL); webRequest.SendChunked = true; using (Stream stream = webRequest.GetRequestStream()) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write(jsonCustGroupId); writer.Flush(); } } string jsonResponse = ReadJsonResponse(webRequest); serviceContracts = JsonConvert.DeserializeObject<Tutorial_CustServiceContract[]>(jsonResponse); return serviceContracts; } } } X++: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.IO; using AuthenticationUtility; namespace Tutorial_ConsumeServiceJSON { class Program { static void Main(string[] args) { JsonServices jsonServices = new JsonServices(); Tutorial_CustServiceContract contract; Tutorial_CustServiceContract[] contracts; contract = jsonServices.getCustDetail("RUMF-000001"); Console.WriteLine(string.Format("{0} | {1} | {2}", contract.parmCustAccount, contract.custAccountName, contract.parmCustGroupId)); contracts = jsonServices.getCustListOfGroup("Орг"); foreach (Tutorial_CustServiceContract iterator in contracts) { Console.WriteLine(string.Format("{0} | {1} | {2}", iterator.parmCustAccount, iterator.custAccountName, iterator.parmCustGroupId)); } Console.ReadLine(); } } } Результат, как и в случае с SOAP должен быть таким же
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 09.12.2020 в 08:56. |
|
|
|