anthonyreilly / NetCoreForce

Salesforce REST API toolkit for .NET Standard and .NET Core
MIT License
110 stars 63 forks source link

When doing Upsert id only being returned when a record is created, not when it's updated #43

Closed tfsmag closed 2 years ago

tfsmag commented 2 years ago

I'm using the UpsertExternal method to do an upsert in saleforce. My problem is that the Id property is empty when the record exists (the update part of "upsert"). The Id is populated when the method creates a recorder (the insert part of upsert).

I believe this is a bug. I'm doing an upsert because our system doesn't know what the salesforce id is for the object we're trying to sync so we use an external id.

it would be very handy to have this method always return the id of the updated record.

Here's the code I'm using to perform the upsert. Works well, just not getting that id on an update.

var sync = await client.UpsertExternalAsync("OPx_Domain__c", "Domain_GUID__c", domainid, domain);

tfsmag commented 2 years ago

Hi Anthony, thanks for picking up this request. I want to let you know that this library has really helped on the current project I'm working on. I really appreciate it. Do you know when this request might make it into the library? If you think it will be awhile I can figure out a workaround so no pressure! Just wanted to check in before I put in effort on my side.

anthonyreilly commented 2 years ago

I did get a chance to look at this, but I wasn't able to reproduce it. (Btw I'm assuming you're using InsertOrUpdateRecord) I did find that the response object is not parsing the "Created" flag that is returned by SF, and I added that in with a new "InsertOrUpdateResponse" object

In both the insert and update cases I am seeing the SF object Id returned in the response object.

I'll try a few other scenarios to see if I can reproduce it.

[Fact]
        public async Task ExternalIdInsertAndUpdate()
        {
            ForceClient client = await forceClientFixture.GetForceClient();

            //create new object
            SfAccount newAccount = new SfAccount();
            string accountName = string.Format("Test Object {0}", Guid.NewGuid().ToString());
            string externalId = Guid.NewGuid().ToString();
            newAccount.Name = accountName;

            InsertOrUpdateResponse insertResponse = await client.InsertOrUpdateRecord<SfAccount>(SfAccount.SObjectTypeName, "AccountExtId__c", externalId, newAccount);
            Assert.True(insertResponse.Created);
            Assert.NotNull(insertResponse.Id);

            //get newly created
            string newAccountId = insertResponse.Id;
            SfAccount account = await client.GetObjectById<SfAccount>(SfAccount.SObjectTypeName, newAccountId);
            Assert.True(account != null, "Failed to retrieve new object");
            Assert.Equal(newAccountId, account.Id);

            //update object description            
            SfAccount accountUpdate = new SfAccount();
            string description = string.Format("Test Description {0}", Guid.NewGuid().ToString());
            accountUpdate.Description = description;
            InsertOrUpdateResponse updateResponse = await client.InsertOrUpdateRecord<SfAccount>(SfAccount.SObjectTypeName, "AccountExtId__c", externalId, accountUpdate);
            Assert.Equal(newAccountId, updateResponse.Id);
            Assert.False(updateResponse.Created);

            //get newly updated
            SfAccount udpatedAccount = await client.GetObjectById<SfAccount>(SfAccount.SObjectTypeName, newAccountId);
            Assert.True(udpatedAccount != null, "Failed to retrieve udpated object");
            Assert.Equal(description, udpatedAccount.Description);

            //delete
            await client.DeleteRecord(SfAccount.SObjectTypeName, newAccountId);
        }
anthonyreilly commented 2 years ago

Just searched for that UpsertExternalAsync method - are you maybe using a different library? the older Force.com-Toolkit-for-NET has that method but mine doesn't

tfsmag commented 2 years ago

Oh my you are so right, it appears that I have your library and the other one mixed up. Please accept my apologies!