{
var client = new HttpClient();
new KeyValuePair < string, string > ("grant_type", "client_credentials"),
new KeyValuePair < string, string > ("client_id", clientId),
new KeyValuePair < string, string > ("client_secret", clientSecret),
new KeyValuePair < string, string > ("scope", scope)
});
{
try
{
HttpResponseMessage response = await client.PostAsync(authUrl, tokenRequest);
response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();
dynamic jsonResponse = JsonConvert.DeserializeObject(content); //must declare using Newtonsoft.Json;
return jsonResponse.access_token;
}
catch (Exception ex)
{
if (i != NumberOfRetries)
{
await Task.Delay(DelayOnRetry);
}
else
{
LogError("GetAccessTokenAsync", ex);
string v = $"Error: {ex.Message}";
return v;
}
}
}
return null;
}
/// 1. Avoid Asynchronous Methods in X++, X++ does not natively support asynchronous methods(async and await) and Task-based programming like C#.
/// 2. Sync Method (GetAccessToken): Uses task.Wait() and task.Result to synchronously wait for the async operation to complete.
/// </summary>
/// <param name="authUrl"></param>
/// <param name="clientId"></param>
/// <param name="clientSecret"></param>
/// <param name="scope"></param>
/// <returns></returns>
public string GetAccessToken(string authUrl, string clientId, string clientSecret, string scope)
{
try
{
// Blocking call to ensure the method is synchronous
var task = GetAccessTokenAsync(authUrl, clientId, clientSecret, scope);
task.Wait(); // Wait for the async task to complete
return task.Result; // Retrieve the result
}
catch (AggregateException aggEx)
{
// Handle potential AggregateException from task.Wait()
for (int i = 0; i < aggEx.InnerExceptions.Count; i++)
{
Exception ex = aggEx.InnerExceptions[i];
LogError("GetAccessToken", ex);
}
return $"Error: {aggEx.Message}";
}
catch (Exception ex)
{
// Handle any other exceptions
LogError("GetAccessToken", ex);
return $"Error: {ex.Message}";
}
}
{
/// <summary>
/// Get Access Token
/// </summary>
/// <returns>Access Token as a string</returns>
public static System.String getAccessToken()
{
//SystemParameters systemParameters = SystemParameters::find();
System.String clientId = "d365fo.client";
System.String clientSecret = "ixxxxxxxxxxxxxxxxxxxxxx";
System.String scope = "xxxxxxAPI";
System.String IntegrationUrl = "https://xxxxxxxx/connect/token";
System.String accessToken;
// Instantiate the DLL object directly
A_Integration.A_ConnectionUtils connection = new A_Integration.A_ConnectionUtils();
accessToken = connection.GetAccessToken(IntegrationUrl, clientId, clientSecret, scope);
return accessToken;
}
{
public static void main(Args _args)
{
System.String accessToken;
try
{
// Call the getAccessToken method from your custom class
accessToken = A_Integration_General::getAccessToken();
info(strFmt("Access Token: %1", accessToken));
}
catch (Exception::CLRError)
{
// Handle any CLR errors that occur during the call
info("An error occurred while retrieving the access token.");
throw error(AifUtil::getClrErrorMessage());
}
catch (Exception::Error)
{
// Handle any other X++ errors
info("An X++ error occurred.");
throw;
}
}
}