How to stop HttpRequestMessage from unencoding %3A to a colon in the request URI (asp.net core)

1.3k Views Asked by At

Using this code...

using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, 
"https://example.com/?var=a%3Ab%3Dc%26d%3Fe")
{
    // Do stuff
}

...request.RequestUri now has the value "https://example.com/?var=a:b%3Dc%26d%3Fe"

Notice the %3A has been unencoded to a colon character, but all other encoded characters remain encoded.

How can I prevent the %3A from being unencoded like all the other encoded characters?

For context, I'm calling an external API. The colon throws an error. I have no control over the external API, so need to find a way of conforming to the API's encoding expectations.

1

There are 1 best solutions below

0
Adrian Sanguineti On

I thought that the behaviour describe was a bit bizarre, so I decided to test this for myself, and indeed in .NET Framework 4.5.1 and 4.7.1, the %3A is decoded as a : by the HttpRequestMessage class.

.NET 4.5.1: dotnet 451 example

.NET 4.7.1: dotnet 471 example

However in .NET Core 2.1.401, this same behaviour does not ocurr with the original string being left intact.

.NET Core 2.1.401: dotnet core example

This is therefore most likely a bug with the HttpRequestMessage implementation in the .NET Framework which was not copied across to .NET Core (which is complete re-write).

I don't have the time to do it myself, but I would recommend raising a bug in the .NET Framework GitHub project, referencing this stack overflow post.

You can also post your issue on the .NET Developer Community to also get some suggestions and workarounds.

Apart from that, I can't think on any workaround to your problem.

UPDATE 1:

Just as I was about to move onto something else, I realized that its the System.Uri class that is actually doing this bug when doing a ToString().

Take the following code as an example:

Uri uri = new Uri("https://example.com/?var=a%3Ab%3Dc%26d%3Fe");
var original = uri.OriginalString;
var toString = uri.ToString();

When executed in .NET Framework: uri.ToString()

As you can see, the original string is correct, but the result of ToString() is wrong.

UPDATE 2:

Now that it's was more obvious what is going on, I was able to dig up this old stackoverflow post: System.Uri and encoded colon (:) and this social MSDN post. Both created quite some time ago and looks like the .NET team never decided to address. I can't get to the Microsoft Connect bug raised from where I am to find out what it resulted in, but the .NET Framework GitHub project and .NET Developer Community pages still may be the best places to get a response from the .NET team directly. (The social MSDN site is mostly non-Microsoft people so will not be as helpful).