Like anything, the Microsoft Dynamics 365 WebAPI has its quirks. It can be confusing at times, and occasionally does some odd things. I’ve compiled here a short list of some of the more confusing aspects of the WebAPI, to stop you from getting caught out.
Request Syntax
The request syntax for most requests is pretty straightforward. Examples of the different WebAPI operations can be found here: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/perform-operations-web-api
Some things that might trip you up:
• GUIDs in WebAPI requests must be clean – this means no enclosing curled braces.
- - If you’re pulling data from lookups on the current form to update another record, ensure that you first remove the curled braces from the GUID before using it in a request.
• Lookups cannot be cleared using an Update (PATCH) request.
- - Lookups must be cleared in the same manner as you would disassociate two records connected via an N:N relationship. The syntax is specified here: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/webapi/associate-disassociate-entities-using-web-api
• Like all HTTP requests, WebAPI requests have a limit on how long the URL can be.
- - This is particularly an issue when retrieving information using a FetchXML request. In this case, you may want to consider using a Batch request, which allows you to specify another request in the body. This will allow you to get around the limitations of a standard GET operation.
• When selecting lookup attributes, the attribute you want to select is not the schema name.
- - Lookup attributes cannot be retrieved by searching for them via schema name (e.g. parentcustomerid). Instead, you need to slightly modify this to retrieve the value of the attribute (_parentcustomerid_value).
• When associating two records via an associate request for an N:N relationship, the request will only work from one side of the relationship.
- - The primary entity is typically the one which the N:N relationship was created from, or the first entity in the relationship schema name. If the request doesn’t work at first, try switching the entities around.
OData binding & Navigation Properties
When updating lookup values, or using lookups in entities submitted to the WebAPI (actions etc.), these must be ‘bound’ – you must use the @odata.bind annotation to set the value.
• When updating lookups, they must be bound to the navigation property. For an OOTB field, this generally looks like this (note the lowercase name, the same as the ‘name’ of the field):
- - ownerid@odata.bind:"/systemusers(1220E456-77FC-E611-80BA-00155D048D79)"
• For a custom field, this changes slightly (note the CamelCase name, same as the ‘schema name’ of the field):
- - mag_VenueId@odata.bind:"/mag_venues(2E32CE85-AE02-E711-80BD-00155D048D79)"
• But when binding a lookup that can have more than one destination type, the syntax changes slightly -> This is the case with the regarding lookup and customer lookups (note the CamelCase name, followed by the logical name of the entity that you’re binding to):
- - mag_CustomerId_account@odata.bind:"/accounts(863487B2-8BFC-E611-80BA-00155D048D79)"
• Similarly for OOTB lookups that have multiple destination types, the syntax changes similarly:
- - parentcustomerid_account@odata.bind:"/accounts(863487B2-8BFC-E611-80BA-00155D048D79)"
Action Endpoints
Calling actions using the WebAPI is fairly simple, but something to remember is there is a small change in syntax when calling a bound action vs calling an unbound action (global).
• Bound Action:
- - http://[Organization URI]/api/data/v9.0/queues(1f7bcc50-d3f6-e511-80d0-00155da84802)/Microsoft.Dynamics.CRM.new_QueueAction
• Unbound Action:
- - http://[Organization URI]/api/data/v9.0/new_GlobalAction
The difference with these, aside from having to call the bound action from the record url, is that when calling a bound action, the action name must be prefixed with ‘Microsoft.Dynamics.CRM.’, whereas when calling a global action, the action is just called with its logical name.