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.