为什么UriBuilder.query不对查询字符串进行转义(url编码)?
为什么UriBuilder.query不对查询字符串进行转义(url编码)?
UriBuilder.Query
属性\"包含在URI中包含的任何查询信息。\"根据文档,“查询信息根据RFC 2396进行转义。”
基于此,并且由于这个属性是可写的,我假设当您设置它时,System.UriBuilder
将解析查询字符串,并按照RFC 2396进行转义(URL编码)。特别是,{和}不在未保留字符集中,因此根据RFC 2396第9页的规定,应该进行转义。但是,System.UriBuilder
似乎没有进行任何转义。
我需要手动对参数进行Server.URLEncode,还是有一种方法可以使System.UriBuilder
处理编码?
这是我的示例代码。您可以在ideone.com上运行此代码并查看,确实没有进行URL编码。
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); } }
实际操作中,我发现您需要手动转义您的查询参数。System.Uri.AbsoluteUri将尝试为您转义它们(如spender的回答中所提到的),但可能不成功。例如,给定值someemail+test@gmail.com
,AbsoluteUri将保留未转义的+,而应该转义为%2B
。否则,当查询字符串解码时,+将被转换为空格,将someemail test@gmail.com
作为最终解码值。
关键是,您需要自己转义它以确保它被正确转义。
通过使用dotPeek检查UriBuilder.Query get/set代码后,我不得不得出结论,文档只是写得很差。它应该说:“查询信息应该根据RFC 2396转义”,而不是“查询信息根据RFC 2396被转义”。
从下面对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); } }