From bde7f4f5776378927eaf5531a9a0ea66e5661035 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Wed, 4 Dec 2024 18:37:58 +0100 Subject: [PATCH 1/2] added routes for getting individial records from Contacts and Accounts lists of Dynamics 365 CRM --- FunctionApp/Dynamics365/CRM/Accounts.cs | 40 ++++++++++++++++++++--- FunctionApp/Dynamics365/CRM/Authorize.cs | 2 +- FunctionApp/Dynamics365/CRM/Contacts.cs | 41 +++++++++++++++++++++--- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/FunctionApp/Dynamics365/CRM/Accounts.cs b/FunctionApp/Dynamics365/CRM/Accounts.cs index 8066185..e263b26 100644 --- a/FunctionApp/Dynamics365/CRM/Accounts.cs +++ b/FunctionApp/Dynamics365/CRM/Accounts.cs @@ -18,15 +18,45 @@ public Accounts(HttpClientProvider httpClientProvider, ILogger logger) } [Function("D365-CRM-Accounts")] - public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req) + public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "crm/accounts/{id?}")] HttpRequest req, Guid? id) { _logger.LogInformation("Dynamics365-CRM-Accounts is requested."); - var client = _httpClientProvider.Create(); - var accountsJson = await client.GetStringAsync("accounts"); - var accounts = JsonValue.Parse(accountsJson); + try + { + var client = _httpClientProvider.Create(); - return new OkObjectResult(accounts?["value"]); + if (!id.HasValue) + { + var accountsJson = await client.GetStringAsync("accounts?$select=accountid,name"); + var accounts = JsonValue.Parse(accountsJson); + return new OkObjectResult(accounts?["value"]); + } + + var accountResponse = await client.GetAsync($"accounts({id})"); + if (!accountResponse.IsSuccessStatusCode) + { + if (accountResponse.StatusCode == System.Net.HttpStatusCode.NotFound) + { + return new NotFoundResult(); + } + + // throws Exception + accountResponse.EnsureSuccessStatusCode(); + } + + var accountJson = await accountResponse.Content.ReadAsStringAsync(); + return new ContentResult() + { + Content = accountJson, + ContentType = "application/json" + }; + } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "An error has occured while processing Dynamics365-CRM-Accounts request."); + return new StatusCodeResult(ex.StatusCode.HasValue ? (int)ex.StatusCode.Value : StatusCodes.Status500InternalServerError); + } } } } diff --git a/FunctionApp/Dynamics365/CRM/Authorize.cs b/FunctionApp/Dynamics365/CRM/Authorize.cs index 53c101a..b959e72 100644 --- a/FunctionApp/Dynamics365/CRM/Authorize.cs +++ b/FunctionApp/Dynamics365/CRM/Authorize.cs @@ -26,7 +26,7 @@ public Authorize(IOptions settings, ILogger logger) } [Function("D365-CRM-Authorize")] - public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req) + public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "crm/authorize")] HttpRequest req) { var scopes = new string[] { $"https://admin.services.crm.dynamics.com/user_impersonation", "offline_access" }; diff --git a/FunctionApp/Dynamics365/CRM/Contacts.cs b/FunctionApp/Dynamics365/CRM/Contacts.cs index 132a995..f0d5ac5 100644 --- a/FunctionApp/Dynamics365/CRM/Contacts.cs +++ b/FunctionApp/Dynamics365/CRM/Contacts.cs @@ -1,3 +1,4 @@ +using Grpc.Core; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.Functions.Worker; @@ -18,15 +19,45 @@ public Contacts(HttpClientProvider httpClientProvider, ILogger logger) } [Function("D365-CRM-Contacts")] - public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req) + public async Task Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = "crm/contacts/{id?}")] HttpRequest req, Guid? id) { _logger.LogInformation("Dynamics365-CRM-Contacts is requested."); - var client = _httpClientProvider.Create(); - var contactsJson = await client.GetStringAsync("contacts"); - var contacts = JsonValue.Parse(contactsJson); + try + { + var client = _httpClientProvider.Create(); - return new OkObjectResult(contacts?["value"]); + if (!id.HasValue) + { + var contactsJson = await client.GetStringAsync("contacts?$select=contactid,fullname"); + var contacts = JsonValue.Parse(contactsJson); + return new OkObjectResult(contacts?["value"]); + } + + var contactResponse = await client.GetAsync($"contacts({id})"); + if (!contactResponse.IsSuccessStatusCode) + { + if (contactResponse.StatusCode == System.Net.HttpStatusCode.NotFound) + { + return new NotFoundResult(); + } + + // throws Exception + contactResponse.EnsureSuccessStatusCode(); + } + + var contactJson = await contactResponse.Content.ReadAsStringAsync(); + return new ContentResult() + { + Content = contactJson, + ContentType = "application/json" + }; + } + catch (HttpRequestException ex) + { + _logger.LogError(ex, "An error has occured while processing Dynamics365-CRM-Contacts request."); + return new StatusCodeResult(ex.StatusCode.HasValue ? (int)ex.StatusCode.Value : StatusCodes.Status500InternalServerError); + } } } } From 139d29dbc98f9d90f9b1a2f93d5cda031813f5d0 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Thu, 5 Dec 2024 11:25:28 +0100 Subject: [PATCH 2/2] upgraded the protocol version --- FunctionApp/Dynamics365/CRM/HttpClientProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FunctionApp/Dynamics365/CRM/HttpClientProvider.cs b/FunctionApp/Dynamics365/CRM/HttpClientProvider.cs index 7a5e718..a82537c 100644 --- a/FunctionApp/Dynamics365/CRM/HttpClientProvider.cs +++ b/FunctionApp/Dynamics365/CRM/HttpClientProvider.cs @@ -24,7 +24,7 @@ public HttpClientProvider(IOptions settings) public HttpClient Create() { var client = new HttpClient(new OAuthMessageHandler(_azureAppSettings, new HttpClientHandler())); - client.BaseAddress = new Uri($"{_azureAppSettings.DynamicsUrl}/api/data/v9.1/"); + client.BaseAddress = new Uri($"{_azureAppSettings.DynamicsUrl}/api/data/v9.2/"); client.Timeout = new TimeSpan(0, 2, 0); client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0"); client.DefaultRequestHeaders.Add("OData-Version", "4.0");