Resolving Contact Creation Issues in Microsoft Dynamics 365 Business Central API
Resolving Contact Creation Issues in Microsoft Dynamics 365 Business Central API
In Business Central, integrating external systems often involves working with the built-in API to handle operations like creating contacts, customers, or vendors. Recently, I faced an issue while trying to create a new contact in the Contact table using the Business Central API. Specifically, the problem occurred when attempting to associate a contact with a company, which caused errors due to unrecognized fields and required data being missing.
In this blog, I will walk through the issue I encountered, how it was diagnosed, and the solution I implemented to resolve it.
The Problem
When attempting to post a contact using a payload like this:
{
"no": "JANE_DOE",
"name": "",
"address": "",
"city": "",
"phoneNo": "",
"email": "",
"type": "Person",
"companyNo": "CT000015"
}
I received the following error message:
{
"error": {
"code": "BadRequest",
"message": "The property 'companyNo' does not exist on type 'NAV.contacts'. Make sure to only use property names that are defined by the type."
}
}
This error occurred because companyNo is not a standard field in the Business Central Contact API, even though it was necessary for my use case of linking a contact to a company.
Solution: Extending the Contact Table
To resolve the issue, I extended the Contact table to include the custom fields required for linking contacts to companies. Here’s the table extension I created:
tableextension 50001 CFS_Contacts extends Contact
{
fields
{
field(50001; CFS_BusinessRelationNo; Code[20])
{
DataClassification = CustomerContent;
Caption = 'Business Relation No.';
Editable = false;
}
field(50002; CFS_ContactNoL; Code[30])
{
DataClassification = CustomerContent;
}
}
trigger OnAfterInsert()
var
rec_contact: Record Contact;
begin
Clear(rec_contact);
rec_contact.SetRange("No.", CFS_ContactNoL);
rec_contact.SetRange(Type, rec_contact.Type::Company);
if rec_contact.FindFirst() then begin
Rec."Company No." := rec_contact."No.";
Rec."Company Name" := rec_contact.Name;
Rec."Contact Business Relation" := rec_contact."Contact Business Relation";
Rec.Modify();
end;
end;
}
This extension ensures that when a new contact is created, the custom field CFS_ContactNoL is used to link the contact to an existing company. Additionally, we update the Company No. and Company Name fields based on the company record in the Contact table.
Important Note on Posting Contacts
When posting contacts, it's crucial to include the companyNo in your payload. This value should correspond to the company with which the contact is associated.
In conjunction with this, I also created a table extension for the Customer table:
tableextension 71983576 CFS_Customer extends Customer
{
fields
{
field(71983575; "CFS_CRM_GUID"; Code[40])
{
Caption = 'CRM GUID';
DataClassification = CustomerContent;
Editable = false;
}
field(71983577; "CFS_BCContact No 2"; Code[20])
{
Caption = 'Contact No.';
FieldClass = FlowField;
CalcFormula = lookup(Contact."No." where (Name = field(Name), "E-Mail" = Field("E-Mail")));
}
}
}
This extension allows you to retrieve the contact number based on the customer's name and email. Before creating a new customer, ensure you first obtain the appropriate companyNo and then use the flow field to link the contact correctly.
Creating the API Page
Next, I created an API page to expose the custom fields and allow external systems to interact with them via the Business Central API.
page 50001 CFS_ContactsAPI
{
APIGroup = 'integration';
APIPublisher = 'cloudfronts';
APIVersion = 'v1.0';
EntityName = 'contact';
EntitySetName = 'contacts';
PageType = API;
SourceTable = Contact;
ODataKeyFields = SystemId;
layout
{
area(content)
{
repeater(General)
{
field(systemId; Rec.SystemId) { }
field("no"; Rec."No.") { }
field(name; Rec.Name) { }
field(address; Rec.Address) { }
field(city; Rec.City) { }
field("phoneNo"; Rec."Phone No.") { }
field("email"; Rec."E-Mail") { }
field("type"; Rec."Type") { }
field("companyNo"; Rec.CFS_ContactNoL) { }
field("faxNo"; Rec."Fax No.") { }
}
}
}
trigger OnOpenPage()
var
IntegrationSetup: Record CFS_IntegrationSetup;
begin
IntegrationSetup.Get();
if not IntegrationSetup.Contacts then
Error('Please enable contacts in the integration setup.');
end;
}
This page ensures that external systems can access and interact with the custom fields, including linking contacts to companies via the companyNo.
Successful POST Request
After making these changes, I sent the following JSON payload to create a new contact linked to a company:
{
"no": "SUNDAYCHECK",
"name": "SUNDAY CHECK",
"type": "Person",
"companyNo": "CT000003",
"countryRegionCode": "US",
"privacyBlocked": false
}
This time, the request was successful, and the contact was correctly linked to the company in Business Central.
Conclusion
The issue arose due to a mismatch between the fields in the Business Central API and the fields in my payload. By extending the Contact table and exposing the new fields through an API page, I was able to resolve the issue and successfully post contacts linked to companies.
This approach demonstrates the flexibility of Business Central in handling custom integrations. If you are facing similar issues, I recommend checking the API metadata and extending the standard objects to fit your needs.
Feel free to reach out if you have questions or need help with similar integrations!