9

How can I force either Uri or HttpWebRequest to allow a uri containing both / and %2f like the following?

http://localhost:55672/api/exchanges/%2f/MyExchange

I tried this...

WebRequest request = 
    HttpWebRequest.Create("http://localhost:55672/api/exchanges/%2f/MyExchange");

...and this...

Uri uri = new Uri("http://localhost:55672/api/exchanges/%2f/MyExchange", true);
WebRequest request = HttpWebRequest.Create(uri);

...and this...

UriBuilder builder = new UriBuilder();
builder.Port = 55672;
builder.Path = "api/exchanges/%2f/MyExchange";
WebRequest request = HttpWebRequest.Create(builder.Uri);

However with all of these, request.RequestUri ends up http://localhost:55672/api/exchanges///MyExchange and request.GetResponse() produces a 404 response.

FYI I'm trying to use RabbitMQ's HTTP API and typing the Url in Chrome produces the expected JSON result.

Clay
  • 10,885
  • 5
  • 47
  • 44
  • I also tried `HttpWebRequest.Create("http://localhost:55672/api/exchanges/%252f/PrintConnector");` What is interesting is that this produces the same `request.RequestUri` as above, but `request.RequestUri.LocalPath` is correctly encoded to `/api/exchanges/%2f/MyConnector` – Clay Jan 28 '13 at 18:23
  • FWIW I've built a .NET client for the RabbitMQ management API that might save you some work: https://www.nuget.org/packages/EasyNetQ.Management.Client/ – Mike Hadlow Jul 24 '13 at 10:02

4 Answers4

8

We just had the same problem and discovered that this problem exists if you are targeting the .NET 4.0 framework. It goes away if you target the .NET 4.5 framework. So if that's an option for you, switch your target framework and it should resolve your issue.

amsimmon
  • 116
  • 2
  • 5
  • Targeting .NET 4.5 fixed it, even without the uri config setting. Perhaps it was a bug in the .NET framework. – Clay Sep 17 '13 at 16:16
  • 1
    Seems to be back in .NET Core 2.0. – X3074861X Jan 03 '19 at 20:46
  • Thanks for this, we managed to easily reproduce this in .NET (we switched between 4.0 and 4.6.1). The problem we're having is when calling the same code from COM interop. The COM DLL is targeting .NET Framework 4.6.1 but we're still getting the 4.0 behaviour (ie the forward slash is un-encoded). We're running out of ideas and getting desperate. When running, Environment.Version is 4.0.30319.42000. – killswitch Aug 16 '22 at 14:11
5

I had this exact same problem when communicating with the RabbitMQ management API a while back. I wrote a blog post about it, including a couple of solutions:

http://mikehadlow.blogspot.co.uk/2011/08/how-to-stop-systemuri-un-escaping.html

You can turn the behavior off either with some nasty reflection into the System.Uri code, or by a setting in App.config (or Web.config):

<uri> 
    <schemeSettings>
        <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
    </schemeSettings>
</uri>
Mike Hadlow
  • 9,427
  • 4
  • 45
  • 37
  • Perhaps I'm doing something wrong, but neither solution seems to work from VS 2010 or 2012 (using console application). `Uri uri = new Uri("http://localhost:55672/api/exchanges/%2f/MyExchange"); Console.WriteLine(uri);` – Clay Jul 24 '13 at 15:41
  • 1
    I use exactly that method in my RabbitMQ.Management.Client library. Have a look here: https://github.com/mikehadlow/EasyNetQ/tree/master/Source/EasyNetQ.Management.Client – Mike Hadlow Jul 26 '13 at 09:56
2

Please use Server.UrlEncode it is required server side or the alternate will be System.Uri.EscapeDataString

HatSoft
  • 11,077
  • 3
  • 28
  • 43
  • Unfortunately Uri.EscapeDataString produces the same result: `request = HttpWebRequest.Create("http://localhost:55672/api/exchanges/" + Uri.EscapeDataString("/") + "/MyExchange");` – Clay Jul 16 '12 at 06:24
1

Use Server.Encode for part containing the reserved characters. http://msdn.microsoft.com/en-us/library/ms525738(v=vs.90).aspx

Paul Fleming
  • 24,238
  • 8
  • 76
  • 113