DeveloperForce ASP.NET / Bulk API / JSON – Issue Upserting Records and Associating with an External ID

bulk-apic#json

We're developing an implementation for a client with SF's ASP.NET DeveloperForce.Force v2.1.0 library and are hopeful that we can get some help on an issue we can't seem to resolve regarding relationships with other objects.

We're following the SF documentation provided here for Bulk API and also in the section entitled "Upserting Records and Associating with an External ID" here for REST API which seem to have the same format.

We are calling the library with batches like this:

var result = await forceClient.RunJobAndPollAsync("Opportunity", "TransactionID__c", BulkConstants.OperationType.Upsert, sObjectList);

This is the actual batch JSON recordlist provided to the method where we are trying to create the relationship between the Opportunity and the Account on the account's external ID field:

[
  [
    {
      "RecordTypeId": "XXXXXXXXXXXXXXXX",
      "TransactionID__c": "1",
      "Account": {
        "Station_ID__c": "47551"
      },
      "Dealer__c": null,
      "Amount": 0,
      "Description": null,
      "Date_Time__c": "2010-04-27T14:41:09Z",
      "Status__c": "Approved",
      "Card_Type__c": "Test Card",
      "Member_Number__c": "111111111",
      "License_Plate__c": null,
      "License_Plate_State__c": null,
      "Service__c": "Full Service",
      "StageName": "Closed Won",
      "CloseDate": "2021-09-09T14:37:43.0371832Z",
      "Name": "Station Transaction"
    }
  ]
]

The response we get back from the server is:

{"Fields":["Account"],"Message":"Opportunity: bad field names on insert/update call: Account","StatusCode":"INVALID_FIELD_FOR_INSERT_UPDATE"}

But when we test using UpsertExternalAsync with the same payload of the first batch item, the record is created and linked successfully:

var result = await forceClient.UpsertExternalAsync("Opportunity", "TransactionID__c", 1);

We need to use batches because we have hundreds of thousands of records to sync. Any assistance you can provide would be greatly appreciated!

Best Answer

We managed to resolve this issue. The library turns the SObject into an XML formatted payload within the code. We had been using strongly typed classes similar to the one below for the Account relationship lookups, which was causing the issue when it was being converted into XML format:

public class OpportunitySObject
{
    public string RecordTypeId { get; } = "000000000000000";
    public int External_ID__c { get; set; }
    public KeyValuePair<string, string> Account { get; set; }
    ...
}

When the KV pair for Account was being passed into the RunJobAndPollAsync method in the SObjectList it resulted in the error we were seeing above because it wasn't being formatted properly in XML.

What we had to do was create a new class to hold the relationship lookup by the Account's external id similar to this:

public class OpportunityAccountRelationshipSObject
{
    public string External_ID__c { get; set; }
}

And modify the base OpportunitySObject by adding a new SObject with the OpportunityAccountRelationshipSObject to it.

We hope that will help anyone else that may encounter it.

Related Topic