Which one to use
- A query string value or a path segment:
Uri.EscapeDataString. It leaves only letters, digits and- . _ ~, and writes spaces as%20, which every server reads the same way. In ASP.NET Core,QueryHelpers.AddQueryStringdoes it for you. - An HTML form body (
application/x-www-form-urlencoded):WebUtility.UrlEncode, which writes spaces as+.FormUrlEncodedContentdoes this for HttpClient. - Decoding:
WebUtility.UrlDecodeturns+into a space;Uri.UnescapeDataStringkeeps it. Use the one that matches how the text was encoded, or a+in the data turns into a space. - Not these:
Uri.EscapeUriStringis obsolete (warning SYSLIB0013: it "can corrupt the Uri string in some cases");HttpUtility.UrlPathEncodeencodes only spaces, control characters and non-ASCII before the?.HttpUtility.UrlEncodeisWebUtility.UrlEncodewith lowercase hex.
Characters outside ASCII are encoded as their UTF-8 bytes (é is %C3%A9). When decoding, bytes that are not valid UTF-8 become U+FFFD in WebUtility and HttpUtility; Uri.UnescapeDataString leaves those %XX as they were.
FAQ
What is the difference between Uri.EscapeDataString and WebUtility.UrlEncode?
EscapeDataString writes a space as %20 and keeps only RFC 3986 unreserved characters (letters, digits, - . _ ~). WebUtility.UrlEncode writes a space as +, keeps ! ( ) * as well, and is meant for form bodies.
Why did my + turn into a space?
The text was decoded with a form decoder (WebUtility.UrlDecode, HttpUtility.UrlDecode, or ASP.NET Core reading a form), where + means a space. Encode a literal + as %2B.
How do I build a URL with query parameters in C#?
Uri.EscapeDataString for each value, or QueryHelpers.AddQueryString(url, name, value) from Microsoft.AspNetCore.WebUtilities, which encodes for you.