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?
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
?).
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.
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.
In my case I solved it by returning ToString() method of UriBuilder class instead of using Uri property of the same class.