假设我想从下面的字符串中创建一个Uri对象。
string url = @"http://someserver.com?param1=1&url=http%3a%2f%2fwww.otherserver.com";
Uri uri = new Uri(url, UriKind.Absolute);
预期的结果是:
http://someserver.com?param1=1&url=http%3a%2f%2fwww.otherserver.com
Obtained:
http://someserver.com/?param1=1&url=http://www.otherserver.com
同样的行为也出现在许多允许创建Uri的相关方法中: Uri.TryCreate, UriBuilder.Uri等。
我如何获得一个保留初始编码参数的Uri?
这种行为是 有据可查:
作为某些方案的构造函数中规范化的一部分,转义表示将被压缩。URI将压缩转义序列的方案包括:file、http、https、net.pipe和net.tcp。对于其他所有的方案,转义序列都不会被压缩。例如:如果你将两个点". "的百分数编码为"%2E%2E",那么URI构造函数将对某些方案压缩这个序列。例如,下面的代码示例显示了http方案的URI构造函数。
因此,一个变通的办法是暂时使用一个自定义的方案(例如 leavemealone://
)来构造URL对象(可能通过 UriBuilder
?).
在.NET4中,您可以为某些方案禁用Uri compaction。通过配置:
<configuration>
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
</schemeSettings>
</uri>
</configuration>
请注意,禁用默认行为会涉及安全问题。
您是如何 "获得 "URL的?如果我在Visual Studio中把鼠标悬停在它上面,它确实会显示解码后的URL。
但每当我通过 AbsoluteUri
属性,它显示的是编码的URL。
在我的例子中,我通过返回UriBuilder类的ToString()方法解决了这个问题,而不是使用同一个类的Uri属性。
我推荐使用库Flurl。它允许流畅和正确地构建和分析URI。请看他们的例子。https:/flurl.devdocsfluent-url)。
它可以作为NuGet包。你不需要HTTP-Stuff包。
using Flurl;
var url = "http://www.some-api.com"
.AppendPathSegment("endpoint")
.SetQueryParams(new {
api_key = ConfigurationManager.AppSettings["SomeApiKey"],
max_results = 20,
q = "Don't worry, I'll get encoded!"
})
.SetFragment("after-hash");