Thursday, October 26, 2023

Inbound SOAP web service in Dynamics 365 Finance needs enum as non extensible

This was a weird one for me, If an inbound SOAP service in X++ expects an enum, such that the contract class defines in the following way


[DataContractAttribute]
public final class myContract 
{
    myEnum myEnum ;
    [DataMemberAttribute('myEnum')]
    public myEnum parmMyEnum (myEnum _myEnum = myEnum )
    {
        myEnum = _myEnum ;
        return myEnum ;
    }
}

Then you need to make sure that the extensible property on mEnum is set to false.

 

Otherwise you get the error in the following format
         <faultstring xml:lang="en-US">The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org:myContract . The InnerException message was 'Invalid enum value 'None' cannot be deserialized into type 'Dynamics.AX.Application.myEnum '. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'.  Please see InnerException for more details.</faultstring>


In essence, the inbound services do not seem to allow extensible enums

In addition, to create a list type of contract classes, I have found this to be the cleanest way

[Newtonsoft.Json.JsonObjectAttribute(IsReference = false)]//Remove $id from Custom Web Service JSON
public class LOKInventoryServiceOutputContractList  
{
    protected List                    inventoryOutputContract;

    [DataMemberAttribute("InventoryList"),
    DataCollectionAttribute(Types::Class, classStr(LOKInventoryServiceOutputContract))]//the name of the class that will be in the list
    public List parmInventoryOutputContract(List _inventoryOutputContract = inventoryOutputContract)
    {
        inventoryOutputContract = _inventoryOutputContract;
        return inventoryOutputContract;
    }

}

D365 Dual write Data Entities call and other issues

 I finally had an opportunity to work on dual write to synchronise data between a CE system and Finance Operations.

MS recommends to use F&O for timesheet entries but our requirement was different, so we had to use CE and then sync it back. To use dual write for this, I had to create a new entity TimesheetLineHdr and the idea was to use the same entity to create and update lines.

The most important bit to start with the process was to know the method call sequence for data entities. The blog helped me with the details

  1. initValue
  2. validateField
  3. validateWrite
  4. update
    1. doUpdate
      1. persistEntity
        1. doPersistEntity
          1. initializeDataSources (for each entity)
            1. initializeEntityDataSource
          2. mapEntityToDataSources (for each entity)
          3. saveDataSources
            1. updateEntityDataSource
          4. updateEntityDataSource/insertEntityDataSource for insert
          5. mapDataSourceToEntity
            1. doSaveDataSource
            2. updateDataSource
              1. preupInsertDataSource
              2. validateWrite of table


!Disable change tracking for initial sync if you want to do inital sync for all records

self refence

If a field is referring to values that dont exist yet but will come in the same sync, remove field and then run the initial sync by disabling change tracking, then add the field again.


Check filters



If the change is not being triggered, check the class BusinessEventsEntityChangeHandler(You can also use this class to track record changes. For "Inserted"/"Updated" events, all scenarios of insert, update,UpdateORInsert_recordset (with without skipDataMEthods) get hit. doinsert,doUpdate does not hit these events).

Check the records on DualWriteProjectConfiguration, DualWriteProjectFieldConfiguration, BusinessEventsDefinition tables to make sure the data against that mapping exists.


If the changes are not being synchronised, the class to lookout for is DualWriteSyncOutbound.

The method WriteEntityRecordToCDS does the main job and you can actually copy the payload from there to copy in your postman and test it manually




D365 CE environment copy issue - Dual write setup can fail if you have restored the dev environment from a production environment. This issue happens because a copy of project parameter gets duplicated as mentioned below




LCS telemetry - debugging issues in tier 2 env


Event Viewer




Debug Mode



Go to table
1)DualWriteProjectConfigurationEntity - turn on
2)DualWriteErrorLog - check the log for column DetailedErrorMsg - ActivityId

Telemetry https://www.youtube.com/watch?v=gjxcoOhegMc