Microsoft Dynamics 365 F&O - URL Encoding
Sometimes Open Data Protocol (OData) routes such as D365 products contain forward slashes, backslashes, or plus signs. You have to double encode those characters, not just the URL. Why? We’ll explain in the subsequent paragraphs.
Issues
One of our clients wanted us to integrate their services into Microsoft Dynamics 365 F&O. Unfortunately for our team, they built the web API with OData. You tend to encounter route issues when URL encoding of resources whose primary key contains plus sign, backslash and forward slash.
Scenario
For example, ProductNumber
= Product1
GET https://pu5c675f84826e91c9deos.cloudax.dynamics.com/data/ProductsV3(ProductNumber='Product1')
The GET request above works fine. However, ProductNumber = 203G08/34S
does not work. Of course, it won’t work because the slash interferes with the route:
GET .../data/ProductsV3(ProductNumber='203G08/34S')
Likewise, encoding the ProductNumber
URL returns a 404 Not Found
error:
GET .../data/ProductsV3(ProductNumber='203G08%2F34S')
Something like this:
Status: 404 Not Found
{
"Message": "No HTTP resource was found that matches the request URI
'.../data/ProductsV3(ProductNumber='203G08/34S')'.
No route data was found for this request."
}
We discovered making a GET
request using the filter parameter works fine if we encode the URL forward slash.
GET .../data/ProductsV3?$filter=ProductSearchName eq '203G08%2F34S'
The result is an array comprising of one time, which means using a similar approach for PUT
, PATCH
, and DELETE
won’t work either. Argh!!!
It results in the error below:
Status: 400 Bad Request
{
"error": {
"code": "",
"message": "An error has occurred.",
"innererror": {
"message": "More than one resource was found when selecting for update.",
"type": "Microsoft.Dynamics.Platform.Integration.Services.OData.ODataArgumentException",
}
}
}
Solution
It’s pretty much a simple solution like everything else in software engineering. The documentation wasn’t well detailed. As it turns out, characters like backslashes, plus signs, and forward slashes requires DOUBLE ENCODING. Sigh!
The following URL works for the product example:
PATCH .../data/ProductsV3(ProductNumber='203G08%252F34S')
Below is an example of a utility we used whilst developing the URLs programmatically:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static string EncodeProductNumber(string stringToEncode)
{
var encodedString = HttpUtility.UrlEncode(stringToEncode).ToUpper();
if (encodedString.Contains("%2F") || encodedString.Contains("%2B") || encodedString.Contains("%5C"))
{
encodedString = encodedString.Replace("%2F", "%252F");
encodedString = encodedString.Replace("%2B", "%252B");
encodedString = encodedString.Replace("%5C", "%255C ");
}
return encodedString;
}
Hopefully, the tip will be useful for you or your team.