We tried connecting the Optimizely Forms to submit to a Leads database in D365.
If all of the form fields are mapping to D365 simple fields such as Single-line of text (text, email, phone, URL) or Option sets, the form submits successfully.
However, if we map a form element to a Lookup field, the form submit throws the following error:
A 'PrimitiveValue' node with non-null value was found when trying to read the value of the property '<field_name>';
however, a 'StartArray' node, a 'StartObject' node, or a 'PrimitiveValue' node with null value was expected.
Full stack trace here:
System.Exception: Unable to save entity for connector: Client-Test, EntityType: lead
---> Microsoft.PowerPlatform.Dataverse.Client.Utils.DataverseOperationException: Error identified in Payload provided by the user for Entity :'leads', For more information on this error please follow this help link https://go.microsoft.com/fwlink/?linkid=2195293 ----> InnerException : Microsoft.OData.ODataException: A 'PrimitiveValue' node with non-null value was found when trying to read the value of the property 'custom_program'; however, a 'StartArray' node, a 'StartObject' node, or a 'PrimitiveValue' node with null value was expected.
---> Microsoft.Rest.HttpOperationException: Operation returned an invalid status code 'BadRequest'
at Microsoft.PowerPlatform.Dataverse.Client.ConnectionService.ExecuteHttpRequestAsync(String uri, HttpMethod method, String body, Dictionary`2 customHeaders, CancellationToken cancellationToken, DataverseTraceLogger logSink, Nullable`1 requestTrackingId, String contentType, Nullable`1 sessionTrackingId, Boolean suppressDebugMessage, HttpClient providedHttpClient)
at Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Command_WebExecuteAsync(String queryString, String body, HttpMethod method, Dictionary`2 customHeaders, String contentType, String errorStringCheck, Guid requestTrackingId)
--- End of inner exception stack trace ---
at Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Create(Entity entity)
at Episerver.Marketing.Connector.MSDynamics.Services.MSDynamicsService.SaveEntity(Guid instanceId, String entityname, Dictionary`2 fields)
at Episerver.Marketing.Connector.MSDynamics.MSDynamicsConnector.CreateEntity(ConnectorDataSource dataSource, Dictionary`2 entityFields)
at Episerver.Marketing.Connector.Framework.MarketingConnectorManager.SaveEntity(IMarketingConnector connector, SaveEntityCriteria saveEntityCriteria, Dictionary`2 entityData)
at Episerver.Marketing.Connector.Forms.Repositories.FormsRepository.PushDataToConnector(IMarketingConnector currentConnector, ConnectorDataSource currentDatasource, Dictionary`2 entityData, Int64 submissionTargetId)
The problem was due to the special handling required for saving values of Lookup fields in D365.
Instead of just this:
entity[fieldName] = value;
Lookup field values has to be set using `EntityReference` specifying the name of the parent lookup object
entity[fieldName] = new EntityReference(lookupEntityName, value);
The D365 SDK used in the connector can also be used to check the type of field, e.g. LookupAttributeMetadata, and the target lookup entity name.
In all honesty, we found a fix for this issue by replacing the implementation of `IMSDynamicsService.SaveEntity()` method.
However, I think this should be fixed on the package level moving forward.
We tried connecting the Optimizely Forms to submit to a Leads database in D365.
If all of the form fields are mapping to D365 simple fields such as Single-line of text (text, email, phone, URL) or Option sets, the form submits successfully.
However, if we map a form element to a Lookup field, the form submit throws the following error:
Full stack trace here:
The problem was due to the special handling required for saving values of Lookup fields in D365.
Instead of just this:
Lookup field values has to be set using `EntityReference` specifying the name of the parent lookup object
The D365 SDK used in the connector can also be used to check the type of field, e.g. LookupAttributeMetadata, and the target lookup entity name.
In all honesty, we found a fix for this issue by replacing the implementation of `IMSDynamicsService.SaveEntity()` method.
However, I think this should be fixed on the package level moving forward.