NetCoreForce icon indicating copy to clipboard operation
NetCoreForce copied to clipboard

updating a field to a null value

Open JanSenkowski opened this issue 1 year ago • 11 comments

Hey is there a way to set a field to null when updating a sf-object?

JanSenkowski avatar Oct 31 '22 11:10 JanSenkowski

I hit the same issue. I'm playing around with JSON attributes for null handling, but no luck yet. This is a big issue with this toolkit, IMHO.

I've tried the following on the object: [JsonObject(ItemNullValueHandling = NullValueHandling.Include)]. And this on an individual field: [JsonProperty(PropertyName = "Skills__c", NullValueHandling = NullValueHandling.Include)]

NOTE: (after more research) This appears to be a limitation of the SF API not the toolkit, however, there is a way around it using fieldsToNull.

In this SF Idea

VanceKInGa avatar Jan 19 '23 12:01 VanceKInGa

I have found that the framework was ignoring null values on serializing the REST payload to send to SF. I am working on a modification that will allow you to specify which fields it should send even if null for each object type.

VanceKInGa avatar Jan 25 '23 17:01 VanceKInGa

The SOAP api has a FieldsToNull property to address this, but I never found an equivalent in the REST api. Dropping the nulls was made the default behavior since that addressed the most typical use case of partial object updates. I'll need to test if if accepts explicit nulls, if so maybe adding an optional fieldstonull parameter on updates to control null handling on a per-property basis might be the way to go

anthonyreilly avatar Jan 25 '23 17:01 anthonyreilly

@VanceKInGa I just tried something that looks like it will work using two options - either globally re-enabling null serialization (which is a bit dangerous) or using a fieldsToNull property in the update call to selectively null out properties to emulate the SOAP API's approach. I've got a working proof of concept that is testing good so far, so I think I'll be able to include this in a 4.0 Beta 2 soon

await client.UpdateRecord<SfAccount>(SfAccount.SObjectTypeName, account.Id, account, ignoreNulls: true, fieldsToNull: new List<string>(){"description"});

anthonyreilly avatar Jan 25 '23 18:01 anthonyreilly

@anthonyreilly, I have a solution working but am finalizing the implementation as I put it in place in our API. If you send a null via the REST API it will null out the field in SF, but as you mentioned, you can't just do that for the entire object because you would wipe out fields you hadn't previously queried.

My approach uses a list of fields that should be serialized even if null, which means it will not serialize any other null values. You can set these prior to an update, or...

In conjunction with this change, I created a QueryBuilder class that can optionally be used to create a query using non-hardcoded SOQL queries. It automatically puts all the fields pulled into the list of fields that should be set to null on an update with each query built.

At it's most basic usage, it is something like this: QueryBuilder query = new QueryBuilder(client, typeof(SfContact), SfContact.SObjectTypeName, new List { nameof(SfContact.Id), nameof(SfContact.ProviderExternalId), nameof(SfContact.MobilePhone), nameof(SfContact.MailingStreet), nameof(SfContact.MailingCity), nameof(SfContact.MailingState) } );

VanceKInGa avatar Jan 26 '23 17:01 VanceKInGa

@VanceKInGa I've added the fieldsToNull parameter to the update/create methods - it sends that down to the serialization contractresolver to control the per-property serialization. These changes are currently in the dev branch with partial test coverage. (I should have used nameof in the tests like you did, I'll update that)

https://github.com/anthonyreilly/NetCoreForce/blob/cc4be924f61007dc6ed007282bd4fb2199dbe62b/src/NetCoreForce.Client/ForceClient.cs#L494

https://github.com/anthonyreilly/NetCoreForce/blob/cc4be924f61007dc6ed007282bd4fb2199dbe62b/src/NetCoreForce.Client/Serializer/CreateableContractResolver.cs

That QueryBuilder looks interesting as well - whenever you have that ready I'd like to see it

anthonyreilly avatar Jan 26 '23 17:01 anthonyreilly

I reworked my QueryBuilder changes based on your null handling in the client. It automatically tracks the fields to set to null based on the ones pulled.

I am ready to create a new branch (dev-QueryBuilder) if you want me to.

VanceKInGa avatar Feb 01 '23 18:02 VanceKInGa

@anthonyreilly, I cannot create a branch. So I am attaching my changes for QueryBuilder.

NetCoreForce.zip

VanceKInGa avatar Feb 07 '23 13:02 VanceKInGa

@anthonyreilly Made a small tweak to make creating the query easier. Should be the last update. NetCoreForce.zip

VanceKInGa avatar Feb 08 '23 15:02 VanceKInGa

@VanceKInGa Thanks, I'll get this merged in

anthonyreilly avatar Feb 14 '23 19:02 anthonyreilly

@anthonyreilly Awesome! I've been working with this for a couple of weeks and added a few ctors to simplify the code. It's pretty tight and powerful now.

NetCoreForce.zip

VanceKInGa avatar Feb 14 '23 19:02 VanceKInGa