How to integrate D365FO with Dataverse using API HTTP requests?
Introduction: Integrating an external API service into Dynamics 365 Finance and Operations allows you to enhance functionality by connecting D365FO to third-party services, systems, or data sources. This can help automate workflows, fetch real-time data, or extend D365FO’s capabilities.
Scenario: In this blog, I have demonstrated how the code queries projects data from D365FO, processes and serializes the data, and then pushes it to an external service via an HTTP API request.
High level resolution steps
- Create a simple batch job.
- Create helper class establishes an HTTP connection and sends a POST request with JSON data to an external API, returning the response message
- Implement the logic in a batch service class to retrieve project data.
- Serialize the data.
- Send the data to an external API.
- Execute the batch job from the user interface.
Step 1: Create a simple batch job; Refer to the link below to create it.
Video blog: Sys Operation framework batch job with parameter X++ – Saina Cloud Software Solutions
Step 2: Create helper class and execute the code below.
Code Snippet:
class SCCPostAPIHelper
{
#define.PatchAPIMethod('Patch')
#define.PutAPIMethod('PUT')
#define.ContentType('application/json')
#define.PostAPIMethod('POST')
#define.GetAPIMethod('GET')
#define.ContentTypeNone('application/none')
public static System.Net.HttpWebRequest connect(str _appURL)
{
System.Net.HttpWebRequest request;
CLRObject clrObj;
System.Exception ex;
System.Net.WebHeaderCollection httpHeader;
try
{
httpHeader = new System.Net.WebHeaderCollection();
clrObj = System.Net.WebRequest::Create(_appURL);
request = clrObj;
}
catch
{
//exception
ex = CLRInterop::getLastException().GetBaseException();
error(ex.get_Message());
}
return request;
}
public str postAPIRequest(str _jsonString, str _appURL)
{
System.Net.HttpWebRequest request = SCCPostAPIHelper::connect(_appURL);
System.Net.HttpWebResponse response;
System.IO.StreamWriter streamWriter;
System.IO.StreamReader streamRead;
str jsonString = _jsonString;
request.Method = #PostAPIMethod;
request.ContentType = #ContentType;
streamWriter = new System.IO.StreamWriter(request.GetRequestStream());
streamWriter.Write(jsonString);
streamWriter.Flush();
streamWriter.Close();
response = request.GetResponse();
streamRead = new System.IO.StreamReader(response.GetResponseStream());
str outputMessage = streamRead.ReadToEnd();
return outputMessage;
}
}
Code Explanation:
This code defines a helper class SCCPostAPIHelper to interact with external APIs. It includes methods to:
- connect: Establishes an HTTP request to a specified URL.
- postAPIRequest: Sends a POST request with JSON data to the external API and returns the response message.
It uses the System.Net.HttpWebRequest and related CLR objects to send data and handle the response.
Step 3: Create a List contract and use the below code.
[DataContractAttribute]
class SCCProjectListContract
{
List productMasterList;
[DataMemberAttribute('productMasterList'), AifCollectionType('_productMasterList', Types::Class, classStr(SCCProjectResponseContract)), AifCollectionType('return', Types::Class, classstr(SCCProjectResponseContract))]
public List parmProductMaster(List _productMasterList = productMasterList)
{
productMasterList = _productMasterList;
return productMasterList;
}
public void new()
{
productMasterList = new List(Types::Class);
}
}
Step 4: Create a Response contract and use the below code
[DataContractAttribute]
class SCCProjectResponseContract
{
ProjId projId;
ProjName projName;
ProjInvoiceProjId projContract;
ProjType projType;
ProjGroupId projGroup;
[DataMemberAttribute("ProjectId")]
public ProjId parmProjId(ProjId _projId = projId)
{
projId = _projId;
return projId;
}
[DataMemberAttribute("ProjectName")]
public ProjName parmProjName(ProjName _projName = projName)
{
projName = _projName;
return projName;
}
[DataMemberAttribute("ProjectContract")]
public ProjInvoiceProjId parmProjectContract(ProjInvoiceProjId _projContract = projContract)
{
projContract = _projContract;
return projContract;
}
[DataMemberAttribute("ProjectType")]
public ProjType parmProjType(ProjType _projType = projType)
{
projType = _projType;
return projType;
}
[DataMemberAttribute("ProjectGroup")]
public ProjGroupId parmProjGroupId(InventSiteId _projGroup = projGroup)
{
projGroup = _projGroup;
return projGroup;
}
}
Step 5: Implement the business logic in a service class. To do that, build a new query to retrieve project data.
- For each project returned by the query, it creates a SCCProjectResponseContract and populates it with project details.
- Adds the populated contract to the projectList.
List projectList = new List(Types::Class);
SCCProjectListContract projectListContract = new SCCProjectListContract();
SCCProjectResponseContract projectResponseContract;
Query projQuery = new Query();
QueryBuildDataSource qbdsProjTable = projQuery.addDataSource(tableNum(ProjTable));
QueryRun qrProj = new QueryRun(projQuery);
while(qrProj.next())
{
ProjTable projTable = qrProj.get(tableNum(ProjTable));
projectResponseContract = new SCCProjectResponseContract();
projectResponseContract.parmProjId(projTable.ProjId);
projectResponseContract.parmProjName(projTable.Name);
projectResponseContract.parmProjectContract(projTable.ProjInvoiceProjId);
projectResponseContract.parmProjType(projTable.Type);
projectResponseContract.parmProjGroupId(projTable.ProjGroupId);
projectList.addEnd(projectResponseContract);
}
projectListContract.parmProductMaster(projectList);
Step 6: Serializes the projectListContract containing project data into a JSON string using FormJsonSerializer::serializeClass.
str jsonString = FormJsonSerializer::serializeClass(projectListContract); |
Step 7: Sends the serialized JSON data via a POST request to an external service using postAPIHelper.postAPIRequest
SCCPostAPIHelper postAPIHelper = postAPIHelper.postAPIRequest(jsonString,’https://prod-94.westus.logic.azure.com:443/workflows/48fba8aabda0481db43cc12ff6884b0f/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=5OnfThew2rAN9DbmGaaHcnRKiPcWKBf0hpWv6JqhUgI’); |
Note: Get the link from an external application. In this example, I have created Power Automate flow with “When an HTTP request is received”. It will generate the link. To learn how to create Power Automate Flow, use the link below.
Service class full code screenshot:
Output:
Project data which we are going to push from dynamics side.
When user can run the batch job in UI. Project data pushed to external application.
Data pushed from Dynamics side using power automate is displayed in the data verse.
Dynamics 365 for Operations Technical Consultant | Passionate about coding, customizations, and workflow optimization