The UriBuilder.Query
property "contains any query information included in the URI." According to the docs, "the query information is escaped according to RFC 2396."
Based on this, and since this property is writable, I assumed that when you set it, System.UriBuilder
would parse your query string, and escape (url encode) according to RFC 2396. In particular, the { and } are not in the unreserved character set, and so they should be escaped according to page 9 of RFC 2396. But, it appears that System.UriBuilder
is not doing any escaping.
Do I need to manually Server.URLEncode the params, or is there a way to get System.UriBuilder
to handle the encoding?
Here's my sample code. You can run this on ideone.com and see that, indeed, nothing is URL encoded.
using System;
public class Test
{
public static void Main()
{
var baseUrl = new System.Uri("http://www.bing.com");
var builder = new System.UriBuilder(baseUrl);
string name = "param";
string val = "{'blah'}";
builder.Query = name + "=" + val;
// Try several different ouput methods; none will be URL encoded
Console.WriteLine(builder.ToString());
Console.WriteLine(builder.Uri.ToString());
Console.WriteLine(builder.Query);
}
}
In practice I have found that you need to manually escape your query params yourself. System.Uri.AbsoluteUri will attempt to escape things for you (as mentioned in spender's answer), but it may not succeed. For instance, given a the value [email protected]
, AbsoluteUri will leave the + unescaped, when it should be escaped as %2B
. Otherwise, when the query string is decoded, the + will be transformed into a space, leaving someemail [email protected]
as the final decoded value.
The bottom line is, you need to escape it yourself to ensure it is escaped correctly.
After reviewing the code in UriBuilder.Query get/set code with dotPeek, I have to conclude that the docs are simply written poorly. Instead of "the query information is escaped according to RFC 2396," it should say "the query information should be escaped according to RFC 2396."
As you can see from the dotPeek decompilation of System.UriBuilder.Query
below, there is no automatic escaping happening in the query getter or setter.
[__DynamicallyInvokable]
public string Query
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
{
return this.m_query;
}
[__DynamicallyInvokable] set
{
if (value == null)
value = string.Empty;
if (value.Length > 0)
value = (string) (object) '?' + (object) value;
this.m_query = value;
this.m_changed = true;
}
}
System.Uri.AbsoluteUri, however, makes an attempt to escape things. Note the call to this.GetParts in the getter:
[__DynamicallyInvokable]
public string Authority
{
[__DynamicallyInvokable] get
{
if (this.IsNotAbsoluteUri)
throw new InvalidOperationException(System.SR.GetString("net_uri_NotAbsolute"));
else
return this.GetParts(UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With