Dynamics 365 Web API get entity using alternate key value that has apostrophe/single quote in it

In Dynamics 365, you can create alternate key for an entity using one of the attributes. Entity can be retrieved using alternate key via Web API. This MSDN article gives you an example on how to do that: https://msdn.microsoft.com/en-us/library/mt607871.aspx#BKMK_UsingAltKeys

I had an interesting error today when performing a query using alternate key. I tried to get an entity record from the User entity (systemusers) using an alternate key that is configured in the User entity. The alternate key uses the internalemailaddress attribute, which contains users' email addresses.

A user's email address is firstname.O'lastname@domain.com, and as you can see, there is an apostrophe/single quote in the email address.

When performing the query via Web API to get the user record, you can construct the below Url and simply paste into the browse to see the JSON response.

In this case, the Url is: https://organization.crm6.dynamics.com/api/data/v8.2/systemusers(internalemailaddress='firstname.O'lastname@domain.com')

You will get an error response from Web API:
"Syntax error: character '@' is not valid at position 38 in '(internalemailaddress='firstname.O'lastname@domain.com')'."

This is because the Url schema for OData uses single quote to denote parameter string value, the apostrophe in the email address tells it the parameter is internalemailaddress='firstname.O', and then the rest of the value in the Url is another parameter. But there is no parameter defined for lastname@domain.com, hence the error.

In this scenario, what you need to do is to use two apostrophes in the email address to represent the single quote, so it will become 'firstname.O''lastname@domain.com'. And to be safe, you can also perform Url encode on the whole string 'firstname.O''lastname@domain.com', that will give you 'firstname.O%27%27lastname%40domain.com'. And if you use this value in the OData query in the Url, it should response with success data.

However, with Dynamics 365 Web API, it still failed after the change, but a different error:

https://organization.crm6.dynamics.com/api/data/v8.2/systemusers(internalemailaddress='firstname.O%27%27lastname%40domain.com')

And response:
"A record with the specified key values does not exist in systemuser entity"

This is very strange, because I am certain the user is in the system. So I tried to query the user using the usual filter query like below:
https://organization.crm6.dynamics.com/api/data/v8.2/systemusers?$filter=internalemailaddress eq 'firstname.O%27%27lastname%40domain.com'

And this time it responded with the user data in JSON, no error!

It seems like the value of this email address has been modified or encoded somehow in the indexing file when the alternate key was created in Dynamics 365. So the email address is stored as it should be in the systemuser table, but different in the indexing file.

At the time of writing, I still haven't figured out how to get this to work. I am going to raise a Microsoft support ticket for this, and will update this post once I have a fix or workaround from Microsoft.

This bug has been fixed in Dynamics 365 version 8.2.1.359.

Comments

Popular posts from this blog

Dynamics 365 sub-grid add new and add existing

Global custom action returns 204 No Content rather than the defined output parameters