Reputation: 2043
The MSDN page for UrlPathEncode states the UrlPathEncode shouldn't be used, and that I should use UrlEncode instead.
Do not use; intended only for browser compatibility. Use UrlEncode.
But UrlEncode does not do the same thing as UrlPathEncode.
My use case is that I want to encode a file system path so that a file can be downloaded. The spaces in a path need to be escaped, but not the forward slashes etc. UrlPathEncode does exactly this.
// given the path
string path = "Directory/Path to escape.exe";
Console.WriteLine(System.Web.HttpUtility.UrlPathEncode(path));
// returns "Installer/My%20Installer.msi" <- This is what I require
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path));
// returns "Installer%2fMy+Installer.msi"
// none of these return what I require, either
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.ASCII));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.BigEndianUnicode));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.Default));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.UTF32));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.UTF7));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.UTF8));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(path, Encoding.Unicode));
Another method I've tried is using Uri.EscapeDataString, but this escapes the slashes.
// returns Directory%2FPath%20to%20escape.exe
Console.WriteLine(Uri.EscapeDataString(path));
If I'm not supposed to use UrlPathEncode, and UrlEncode doesn't produce the required output, what method is equivalent and recommended?
Upvotes: 6
Views: 1167
Reputation: 2043
It's funny that when trying to write a question properly, you find your answer:
Uri.EscapeUriString(path);
Produces the required output.
I do think the MSDN page should reflect this, though.
Edit (2020-11-22)
I've recently come across this again, but needing to URL encode URLs with special characters (instead of file names with spaces), but it's essentially the same thing. The approach I used this time was to instantiate the Uri class:
var urlWithSpecialChars = "https://www.example.net/something/contàins-spécial-chars?query-has=spécial-chars-as-well";
var uri = new Uri(urlWithSpecialChars);
// outputs "https://www.example.net/something/contàins-spécial-chars?query-has=spécial-chars-as-well"
Debug.WriteLine(uri.OriginalString);
// outputs "https://www.example.net/something/cont%C3%A0ins-sp%C3%A9cial-chars?query-has=sp%C3%A9cial-chars-as-well"
Debug.WriteLine(uri.AbsoluteUri);
// outputs "/something/cont%C3%A0ins-sp%C3%A9cial-chars?query-has=sp%C3%A9cial-chars-as-well"
Debug.WriteLine(uri.PathAndQuery);
This give you quite a bit of useful Uri properties that are likely to cover most/many Uri processing requirements:
Upvotes: 6