For training and consulting, write to us at info@xrmforyou.com
If you have used alternate keys in Dynamics 365 and tried to update using a record using WebAPI alternate key, you know the default behavior of how it works.For example, let’s see the sample code below.
// JavaScript source code function UpdateRecord(e) { var fc = e.getFormContext(); var serverURL = fc.getClientUrl(); var request = new XMLHttpRequest(); request.open("PATCH", serverURL + "/api/data/v9.1/contacts(emailaddress1='debajit.dutta@xrmforyou.com')", true); request.setRequestHeader("Accept", "application/json"); request.setRequestHeader("Content-Type", "application/json; charset=utf-8"); request.setRequestHeader("OData-MaxVersion", "4.0"); request.setRequestHeader("OData-Version", "4.0"); request.onreadystatechange = function () { if (this.readyState === 4) { request.onreadystatechange = null; if (this.status === 204) { console.log("record updated successfully."); } else { var error = JSON.parse(this.response).error; console.log(error.message); } } }; var data = {}; data.firstname = "Debajit"; data.lastname = "Dutta"; var body = JSON.stringify(data); request.send(body); }
Here an alternate key is created on “emailaddress1” field of the contact entity. And what I am trying is to update a record using alternate key. The email I am looking for here is – debajit.dutta@xrmforyou.com
You may be wondering – I already know the code
If you know it, you know as well that in the above code, if there is no contact with email address – debajit.dutta@xrmforyou.com, it will try to create a record, else it will update. However in my case, the requirement was to only update and not create. if there is no contact with the email provided, system should throw an error. Wondering how to do it?
It’s pretty simple trick actually. All you need to use one more header – If-Match.
In the code I will just add one more line
request.setRequestHeader("If-Match", "*");
This basically directs the upsert operation to work like a basic update and not update and insert.
Below error you will encounter if you now use the above code and try with an email that does not match for any contact in Dynamics 365.
Wondering if there is any similar header for the upsert to work only with create and not update. Well, there is. The equivalent header is “If-None-Match”.
Hope this helps!
Debajit Dutta
(Microsoft MVP)
Discover more from Debajit's Power Apps & Dynamics 365 Blog
Subscribe to get the latest posts sent to your email.
Hi Debajit, Thank’s for your post, it’s very useful and I had a similar scenario that is now working. It is failing however in some cases, I’m not sure if it could be some bug in D365.
The case is that I have a custom entity with an alternate key
“alssc_ANGLESector@odata.bind”: “/alssc_anglesectors(alssc_name=’Air’)”,
“alssc_ANGLESector@odata.bind”: “/alssc_anglesectors(alssc_name=’Water Auth/Company’)”,
when I create an account and use the first bind with “Air” it works fine, while when using the second “Auth/Company” I got the response
“message”: “Bad Request – Error in query syntax.”,
“type”: “Microsoft.OData.ODataException”,
“stacktrace”: ” at Microsoft.OData.UriParser.ODataPathParser.ExtractSegmentIdentifierAndParenthesisExpression(String segmentText, String& identifier, String& parenthesisExpression)
I’m not being able to overcome this, Any ideias / suggestions ?
Thank you in advance.
Regards,
Manuel
Hi Manuel,
thanks for reading my blog. at first glance I believe the “/” in Auth/Company may be the culprit. Can you encode these value before passing the same.
-Debajit
Hi @Debajit,
Thanks for the quick answer. It is for sure the cause of the error. I’ve tried to encode with the following but got the same end result:
“alssc_ANGLESector@odata.bind”: “/alssc_anglesectors(alssc_name=\u0027Water Auth\u002FCompany\u0027)”,
“message”: “Bad Request – Error in query syntax.”, 🙁
Hi Manuel,
can u use encodeUriComponent
I’ve tried also.. 🙁
“alssc_ANGLESector@odata.bind”: “/alssc_anglesectors(alssc_name=’Water%20Auth%2FCompany’)”,
same result …
var uri = “‘Water Auth/Company'”;
var res = encodeURIComponent(uri);