How to include the number (hash) # in the path segment?
I need to upload a file (using existing Flurl-Http [1] endpoints) whose name contains " # ", which of course must be escaped to% 23 so as not to conflict with uri-detection fragments.
But Flurl always avoids the rest, but not this character, as a result of which the uri does not work, where half the path and all request parameters are missing, since they were parsed as a uri fragment:
Url url = "http://server/api";
url.AppendPathSegment("item #123.txt");
Console.WriteLine(url.ToString());
Returns: http://server/api/item%20#123.txt
This means that the HTTP request (using Flurl.Http
) will try to load a non-existent resource http://server/api/item%20
.
Even when I remove the segment beforehand, the result is still the same:
url.AppendPathSegment("item %23123.txt");
Console.WriteLine(url.ToString());
Returns: http://server/api/item%20#123.txt
.
How to stop this "magic"?
[1] This means I have delegates / interfaces where input is an existing instance Flurl.Url
that I have to modify.
source to share
It looks like you found a bug. Here are the documented rules for coding Flurl follows:
- Query string values are fully URL encoded.
- For path segments, reserved characters such as / and% are not encoded.
- Illegal characters such as spaces are encoded for route segments.
- For path segments ,? the character is encoded as the query strings receive special treatment.
According to the second point, it shouldn't encode #
in the path, so the way it handles AppendPathSegment("item #123.txt")
is correct. However, when you code #
to %23
yourself, Flurl certainly doesn't have to unencode it. But I have confirmed what is going on. I invite you to post an issue on GitHub and it will be reviewed.
At the same time, you can write your own extension method to cover this case. Something like this should work (and you don't even need to pre-code #
):
public static Url AppendFileName(this Url url, string fileName) {
url.Path += "/" + WebUtility.UrlEncode(fileName);
return url;
}
source to share