Calling an External API from D365FO Using X++ to Retrieve a Token

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

Popular posts from this blog

JSON-Based HTTP POST Request from X++ to Retrieve an Access Token

Restricting Date Selection in Dynamics 365 FO using X++