Becca
Becca

Reputation: 1580

Why does Uri partially decode the query part?

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

Answers (3)

Jared Phelps
Jared Phelps

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

AmandaSai98b
AmandaSai98b

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

dlev
dlev

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

Related Questions