在Flurl http get请求中处理双重编码

时间:2018-10-10 11:49:09

标签: c# flurl

在理解如何使用flurl在请求中传递编码数据时有些麻烦。 我们有一个如下所示的api:

https://servicename.com/domain/api/{identifier}?parameter=value

在某些特定情况下,我们有包含正斜杠/

的标识符

我们正在使用以下代码构建请求:

var clientRequest = this.configuration.Client
            .Request(this.configuration.RequestPath)
            .AppendPathSegment(identifier)
            .WithHeader("Requesting-System", "api");

我们用以下方式称呼它:

using (var response = await clientRequest.GetAsync(cancellationToken))
{
    return await response.Content.ReadAsStringAsync();
}

现在。采用直截了当的方法,即只用正斜杠传递标识符;假设是abc / 123。上面的代码生成一个

路径的clientRequest。
https://servicename.com/domain/api/abc/123?parameter=value

预期会失败,并显示400错误。因此,基于我们的api规范,此解决方案是将正斜杠编码为%2F,并将其传递到url中。值得庆幸的是,Flurl通过在AppendPathSegment方法中允许使用可选参数来使编码变得很简单,从而在理论上变得非常容易。 因此,我们将以上内容修改为使用

.AppendPathSegment(identifier, true)

哪个生成带有

路径的clientRequest
https://servicename.com/domain/api/abc%2F123?parameter=value

完全符合我的期望。如果我使用邮递员调用此URL,则可以看到期望从API获得的正确响应。

但是,当我使用GetAsync方法调用它(与上面相同)时,我仍然收到400 Sub-Resource not found错误;在我的日志中,我可以看到实际的请求是

https://servicename.com/domain/api/abc/123?parameter=value

服务调用过程中是否存在Flurl解码url字符串的问题?如果是这样,如何将%2F传入?

尝试了双重编码,因此请求包含标识符abc%252F123。鉴于以上情况,我希望可以将其解码为abc%2F123,然后将其发送到我们的API。但是在这种情况下,不会进行解码,并且请求网址为

https://servicename.com/domain/api/abc%252F123?parameter=value

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这似乎是System.Uri中的bug or quirk(取决于询问的人),HttpClient在调用堆栈的深处使用。解决方法是将其添加到app.config或web.config:

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

所有功劳归于this answer

如果可能的话,我会尽量避免在标识符中保留保留的URL字符。这似乎很吸引人。如果那不可能,也许想出自己的转义序列来表示正斜杠。