在.NET中创建一个Uri时,会自动对所有通过的字符串参数进行urldecodes。

问题描述 投票:9回答:5

假设我想从下面的字符串中创建一个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?

c# .net url escaping
5个回答
3
投票

这种行为是 有据可查:

作为某些方案的构造函数中规范化的一部分,转义表示将被压缩。URI将压缩转义序列的方案包括:file、http、https、net.pipe和net.tcp。对于其他所有的方案,转义序列都不会被压缩。例如:如果你将两个点". "的百分数编码为"%2E%2E",那么URI构造函数将对某些方案压缩这个序列。例如,下面的代码示例显示了http方案的URI构造函数。

因此,一个变通的办法是暂时使用一个自定义的方案(例如 leavemealone://)来构造URL对象(可能通过 UriBuilder?).


6
投票

在.NET4中,您可以为某些方案禁用Uri compaction。通过配置:

<configuration>
  <uri>
    <schemeSettings>
      <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes"/>
    </schemeSettings>
  </uri>
</configuration>

请注意,禁用默认行为会涉及安全问题。


4
投票

您是如何 "获得 "URL的?如果我在Visual Studio中把鼠标悬停在它上面,它确实会显示解码后的URL。

但每当我通过 AbsoluteUri 属性,它显示的是编码的URL。


0
投票

在我的例子中,我通过返回UriBuilder类的ToString()方法解决了这个问题,而不是使用同一个类的Uri属性。


0
投票

我推荐使用库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");
© www.soinside.com 2019 - 2024. All rights reserved.