9

Suppose I want to create an Uri object from the following string:

string url = @"http://someserver.com?param1=1&url=http%3a%2f%2fwww.otherserver.com";
Uri uri = new Uri(url, UriKind.Absolute);

Expected result would be:

http://someserver.com?param1=1&url=http%3a%2f%2fwww.otherserver.com 

Obtained:

http://someserver.com/?param1=1&url=http://www.otherserver.com

The same behavior is noticed in many related methods that allow Uri creation: Uri.TryCreate, UriBuilder.Uri, etc.

How would I get an Uri that preserve initial encoded parameter?

abatishchev
  • 95,331
  • 80
  • 293
  • 426
Eugeniu Torica
  • 7,266
  • 11
  • 46
  • 62
  • Expected result of doing what? If I try your code in a Console Application `Console.WriteLine(uri.AbsoluteUri);` returns the encoded url – Paolo Falabella Sep 05 '11 at 12:16
  • 1
    For other searching regarding this. It is actually the ToString() method that decodes the string. .OriginalString or .AbsoluteUri will return the encoded string. For a relative url, use .PathAndQuery – jishi Feb 17 '14 at 15:01

5 Answers5

6

In .NET4 you can disable Uri compaction for certain scheme via a configuration:

<configuration>
  <uri>
    <schemeSettings>
      <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
    </schemeSettings>
  </uri>
</configuration>

Note that there are security implications related to disabling of the default behaviour.

John Gietzen
  • 47,524
  • 30
  • 142
  • 185
Pencho Ilchev
  • 3,152
  • 17
  • 21
4

How did you "obtain" the URL? If I hover my mouse over it in Visual Studio, it indeed shows the decoded URL.

But whenever I access it through the AbsoluteUri property, it shows the encoded URL.

CodeCaster
  • 139,522
  • 20
  • 204
  • 252
3

This behavior is documented:

As part of canonicalization in the constructor for some schemes, escaped representations are compacted. The schemes for which URI will compact escaped sequences include the following: file, http, https, net.pipe, and net.tcp. For all other schemes, escaped sequences are not compacted. For example: if you percent encode the two dots ".." as "%2E%2E" then the URI constructor will compact this sequence for some schemes. For example, the following code sample shows a URI constructor for the http scheme.

So one workaround might be temporarily using a custom scheme (e.g. leavemealone://) to construct the URL objects (possibly through UriBuilder?).

Jon
  • 413,451
  • 75
  • 717
  • 787
  • Interestingly, I discovered the compaction to also occur with `rtsp://`. The documentation is vague about which are included (saying "some" schemes are left uncompacted, and ones which are compacted "include" these). – Joseph Aug 22 '19 at 00:08
0

I recommend using the library Flurl. It allows a fluent and correct build and analysis of URIs. See their examples. https://flurl.dev/docs/fluent-url/

It is available as NuGet package. You don't need the HTTP-Stuff

    using Flurl;

    var url = "http://www.some-api.com"
    .AppendPathSegment("endpoint")
    .SetQueryParams(new {
        api_key = ConfigurationManager.AppSettings["SomeApiKey"],
        max_results = 20,
        q = "Don't worry, I'll get encoded!"
    })
    .SetFragment("after-hash");
Robetto
  • 719
  • 7
  • 20
0

In my case I solved it by returning ToString() method of UriBuilder class instead of using Uri property of the same class.

Eugeniu Torica
  • 7,266
  • 11
  • 46
  • 62