4

我必须下载一个文件(使用现有的 Flurl-Http 端点 [1]),其名称包含一个“ # ”,当然必须将其转义到 %23 以免与 uri-fragment 检测冲突。

但是 Flurl 总是会转义其余部分,但不会转义这个字符,从而导致 uri 无法正常工作,其中一半的路径和所有查询参数都丢失了,因为它们被解析为 uri-fragment:

Url url = "http://server/api";
url.AppendPathSegment("item #123.txt");
Console.WriteLine(url.ToString());

回报:http://server/api/item%20#123.txt

这意味着 http 请求(使用Flurl.Http)只会尝试下载不存在的资源http://server/api/item%20

即使我预先转义该段,结果仍然完全相同:

url.AppendPathSegment("item %23123.txt");
Console.WriteLine(url.ToString());

再次返回:http://server/api/item%20#123.txt

有什么办法可以阻止这种“魔法”的发生?

Flurl.Url[1] 这意味着我有委托/接口,其中输入是我必须修改的现有实例。

4

2 回答 2

3

看起来你发现了一个错误。以下是Flurl 遵循的文档化编码规则:

  • 查询字符串值是完全 URL 编码的。
  • 对于路径段,不编码保留字符,例如 / 和 %。
  • 对于路径段,对空格等非法字符进行编码。
  • 对于路径段,? 字符被编码,因为查询字符串得到特殊处理。

根据第二点,它不应该#在路径中编码,所以它的处理AppendPathSegment("item #123.txt")方式是正确的。但是,当您自己编码时#%23Flurl 肯定不应该取消编码。但我已经确认这是正在发生的事情。我邀请您在 GitHub 上创建一个问题,它会得到解决。

同时,您可以编写自己的扩展方法来涵盖这种情况。像这样的东西应该可以工作(你甚至不需要 pre-encode #):

public static Url AppendFileName(this Url url, string fileName) {
    url.Path += "/" + WebUtility.UrlEncode(fileName);
    return url;
}
于 2017-07-31T16:59:04.050 回答
0

我最终使用了,Uri.EscapeDataString(foo)因为建议WebUtility.UrlEncode用我不想要的“+”替换空格。

于 2020-01-15T13:30:47.397 回答