In many Dynamics 365 Finance & Operations (D365FO) integrations, we need to authenticate with an external system before making API calls. The authentication is usually done by sending credentials (such as email, password, and API token) to the endpoint, which returns a JWT (JSON Web Token) or similar authentication token.
In this post, I’ll share how I implemented an X++ method that:
-
Sends login details to an external API in JSON format.
-
Reads the API response.
-
Deserializes the JSON into a usable object.
-
Includes error handling for robust integration.
Requirement
Connect to an external REST API, send authentication details stored in the HRMParameters table, and retrieve an authentication token for use in subsequent API calls.
Approach
-
Use CLR Interop to call .NET classes from X++.
-
Build a JSON request body using strFmt.
-
Send the request via System.Net.HttpWebRequest.
-
Read the API’s JSON response.
-
Deserialize it into a custom ResponseTokenData class.
-
Handle errors gracefully with try-catch.
X++ Code
public ResponseTokenData getToken()
{
System.Net.HttpWebRequest request;
System.Net.HttpWebResponse response;
System.IO.StreamWriter streamWriter;
System.IO.StreamReader streamReader;
System.IO.Stream responseStream;
CLRObject clrObj;
System.Exception ex;
str jsonBody, responseData;
ResponseTokenData tokenResponse = new ResponseTokenData();
HRMParameters hrmParameters = HRMParameters::find();
new InteropPermission(InteropKind::ClrInterop).assert();
try
{
// Prepare JSON body
jsonBody = strFmt(@'{
"email": "%1",
"password": "%2",
"Token": "%3"
}',
hrmParameters.TokenRequestEmail,
hrmParameters.TokenRequestPassword,
hrmParameters.Token);
// Create HTTP request
clrObj = System.Net.WebRequest::Create("https://greenstarreplicaapi.flowhcm.com/api/IntegrationSettings/IntegrationLogin");
request = clrObj;
request.Method = "POST";
request.ContentType = "application/json";
request.Accept = "application/json";
request.get_Headers().Add("Accept-Encoding", "identity");
// Write request body
streamWriter = new System.IO.StreamWriter(request.GetRequestStream());
streamWriter.Write(jsonBody);
streamWriter.Flush();
streamWriter.Close();
// Send request and get response
response = request.GetResponse();
responseStream = response.GetResponseStream();
streamReader = new System.IO.StreamReader(responseStream);
responseData = streamReader.ReadToEnd();
info(strFmt("Raw response: %1", responseData));
// Deserialize JSON into ResponseTokenData
tokenResponse = FormJsonSerializer::deserializeObject(classIdGet(tokenResponse), responseData);
info(strFmt("Token: %1", tokenResponse.parmToken()));
}
catch (Exception::CLRError)
{
ex = CLRInterop::getLastException().GetBaseException();
error(strFmt("API Error: %1", ex.get_Message()));
}
return tokenResponse;
}
Comments
Post a Comment