处理 Flurl http get 请求中的双重编码
Dealing with double-encoding in Flurl http get requests
我在理解如何使用 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 recognized 错误;在我的日志中,我可以看到实际请求是
https://servicename.com/domain/api/abc/123?parameter=value
Flurl 对 url 字符串进行解码的服务调用期间是否有一点?如果是这样,我该如何传递 %2F?
已尝试双重编码,使请求中包含标识符abc%252F123。鉴于上述情况,我本以为它会被解码为 abc%2F123,然后将其发送到我们的 API。但是在这种情况下没有解码发生,并且请求 url 是
https://servicename.com/domain/api/abc%252F123?parameter=value
非常感谢您的帮助。
这似乎是 bug or quirk(取决于您问的人)与 System.Uri
,HttpClient
在调用堆栈的深处使用。解决方法是将其添加到 app.config 或 web.config:
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
所有功劳归于this answer。
如果可能的话,我首先会避免在您的标识符中使用保留 URL 字符。它似乎只是在邀请怪癖。如果那不可能,或许想出您自己的转义序列来表示正斜杠。
我在理解如何使用 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。上面的代码生成了一个路径为
的clientRequesthttps://servicename.com/domain/api/abc/123?parameter=value
这预计会失败并出现 400 错误。因此,根据我们的 api 规范,解决方案是将正斜杠编码为 %2F,并将其传递到 url 中。值得庆幸的是,Flurl 通过在 AppendPathSegment 方法中允许一个可选参数(这将导致编码),使这在理论上变得非常容易。 所以我们修改上面的使用
.AppendPathSegment(identifier, true)
生成路径为
的 clientRequesthttps://servicename.com/domain/api/abc%2F123?parameter=value
正是我所期望看到的。如果我使用邮递员调用此 URL,那么我可以从 API.
中看到我期望的正确响应但是,当我使用 GetAsync 方法调用它时(同上),我仍然收到 400 Sub-Resource not recognized 错误;在我的日志中,我可以看到实际请求是
https://servicename.com/domain/api/abc/123?parameter=value
Flurl 对 url 字符串进行解码的服务调用期间是否有一点?如果是这样,我该如何传递 %2F?
已尝试双重编码,使请求中包含标识符abc%252F123。鉴于上述情况,我本以为它会被解码为 abc%2F123,然后将其发送到我们的 API。但是在这种情况下没有解码发生,并且请求 url 是
https://servicename.com/domain/api/abc%252F123?parameter=value
非常感谢您的帮助。
这似乎是 bug or quirk(取决于您问的人)与 System.Uri
,HttpClient
在调用堆栈的深处使用。解决方法是将其添加到 app.config 或 web.config:
<uri>
<schemeSettings>
<add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" />
</schemeSettings>
</uri>
所有功劳归于this answer。
如果可能的话,我首先会避免在您的标识符中使用保留 URL 字符。它似乎只是在邀请怪癖。如果那不可能,或许想出您自己的转义序列来表示正斜杠。