Reputation: 1580
Background: I'm trying to some some URL manipulation for an MVC application. I've written an HtmlHelper extension method that replaces on query string value with another. The method takes the current request string, manually splits the query part (so as to prevent Foo=1&Foo=Hello%2c%20World!&Foo=2 from being read as Foo=1,Hello, World,2), and then tries to use UriBuilder and Uri to get a URL.
Problem: For some reason, Uri.ToString partially decodes query strings. As a quick test, I fired up LINQPad and ran the following:
var ub = new System.UriBuilder("http://foobar");
ub.Query = "NY%26A"; // NY&A
ub.Uri.Dump();
ub.Uri.ToString().Dump();
ub.Uri.Query.Dump();
ub.ToString().Dump();
The results are:
http://foobar/?NY&A
http://foobar/?NY&A
?NY%26A
http://foobar:80/?NY%26A
I say partially decoding, because if I use lots of escaped characters, it decodes some and leaves others in place:
var ub = new System.UriBuilder("http://foobar");
ub.Query = "!%40%23%24%25%5E%26*()"; // !@#$%^&*()
ub.Uri.Dump();
ub.Uri.ToString().Dump();
ub.Uri.Query.Dump();
ub.ToString().Dump();
And the results:
http://foobar/?!@%23$%25^&*()
http://foobar/?!@%23$%25^&*()
?!%40%23%24%25%5E%26*()
http://foobar:80/?!%40%23%24%25%5E%26*()
Question: Can someone explain what is going on?
Upvotes: 2
Views: 618
Reputation: 473
If the Uri was constructed from a string, Uri.OriginalString is an easy way to get back to that original string, with the original encoding.
Upvotes: 0
Reputation: 505
Because URI does use url encode
you can use this to read the original or add encoded value to URI object:
System.Web.HttpUtility.UrlDecode("NY%26A");
System.Web.HttpUtility.UrlEncode("NY&A");
Upvotes: 1
Reputation: 48596
It appears to be using "safe" decoding. In your second example, it won't decode # or %, because that would change the structure/meaning of the URI.
If you don't want that decoding to happen, stop calling .ToString()
on the URI, and instead access the components you want directly.
Upvotes: 1