UriBuilder.Query属性“包含URI中包含的任何查询信息。”According to the docs,“根据RFC2396对查询信息进行转义。”
基于此,由于此属性是可写的,我假设当您设置它时,System.UriBuilder将解析您的查询字符串,并根据RFC2396进行转义(url编码)。特别是,{和}不在非保留字符集,因此不是they should be escaped according to page 9 of RFC 2396。但是,看起来System.UriBuilder并没有进行任何转义。
我是否需要手动Server.URLEncode参数,或者有没有办法让System.UriBuilder来处理编码?
下面是我的示例代码。你可以使用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);
}
}发布于 2014-07-05 01:02:09
builder.Uri.AbsoluteUri是您要查找的droid,在您的示例中,它返回
http://www.bing.com/?param=%7B'blah'%7D
考虑到很难知道是否应该对&、+或=符号进行编码,在为.Query属性赋值时自己进行转义可能更好。
发布于 2014-07-07 21:26:39
在实践中,我发现您需要自己手动转义查询参数。System.Uri.AbsoluteUri将尝试为您转义(如spender's answer中提到的),但它可能不会成功。例如,给定一个值someemail+test@gmail.com,当+应该被转义为%2B时,AbsoluteUri将不对+进行转义。否则,当查询字符串被解码时,+将被转换为一个空格,留下someemail test@gmail.com作为最终的解码值。
底线是,您需要自己对它进行转义,以确保它被正确转义。
在使用dotPeek查看了UriBuilder.Query get/set代码中的代码之后,我不得不得出结论,文档只是写得很糟糕。而不是“查询信息是根据RFC2396的转义”,而应该是“查询信息应该是根据RFC2396的转义”。
从下面对System.UriBuilder.Query的dotPeek反编译中可以看到,在查询的getter或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试图逃避一些事情。注意getter中对this.GetParts的调用:
[__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);
}
}https://stackoverflow.com/questions/24576239
复制相似问题