Is there a difference between Server.UrlEncode and HttpUtility.UrlEncode?
6 Answers
I had significant headaches with these methods before, I recommend you avoid any variant of UrlEncode
, and instead use Uri.EscapeDataString
- at least that one has a comprehensible behavior.
Let's see...
HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
//standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
// want, since you still need to
// escape special characters yourself
But my personal favorite has got to be HttpUtility.UrlPathEncode - this thing is really incomprehensible. It encodes:
- " " ==> "%20"
- "100% true" ==> "100%%20true" (ok, your url is broken now)
- "test A.aspx#anchor B" ==> "test%20A.aspx#anchor%20B"
- "test A.aspx?hmm#anchor B" ==> "test%20A.aspx?hmm#anchor B" (note the difference with the previous escape sequence!)
It also has the lovelily specific MSDN documentation "Encodes the path portion of a URL string for reliable HTTP transmission from the Web server to a client." - without actually explaining what it does. You are less likely to shoot yourself in the foot with an Uzi...
In short, stick to Uri.EscapeDataString.

- 11,422
- 8
- 28
- 49

- 47,023
- 20
- 101
- 166
-
5And unfortunately that still doesn't work when doing HTTP requests against some web servers -- Uri.EscapeDataString() doesn't encode "!" or "'", which differs from how most browser implementations of escape() work... – Chris R. Donnelly Aug 11 '09 at 20:30
-
8! and ' characters are not supposed to be encoded; but if a buggy webserver requires this, it's easy to workaround. Avoid javascript's escape function - it's inherently buggy (impossible to roundtrip, for one). See http://xkr.us/articles/javascript/encode-compare/ - but in short; you can use encodeUriComponent() instead, which behaves similarly to EscapeDataString - it predictably and reversibly encodes a string, and also does not encode ! and ' characters. – Eamon Nerbonne Aug 12 '09 at 08:35
-
2This is old, but the question got bumped to the front page, so.... The path part of a url string is the part between the domain and the ? or # in a url. – Powerlord Dec 23 '09 at 14:54
-
@R. Bemrose: sure, that is the case: but it doesn't explain the behaviour of UrlPathEncode. Presumably, it should never corrupt your url (which it does, not encoding %, for instance), and in any case, if your url is already correctly delimited into components by ? and # tokens, what's the point of further encoding? If the url path contains tokens that need encoding, then it's obviously not safe to pass the entire url to the encoding function - that's an invalid and perhaps corrupted url, almost by definition. In short, the function isn't specified and its most reasonable use is impossible. – Eamon Nerbonne Jan 26 '10 at 15:02
-
UrlPathEncode doesn't touch anything after the ? because it assumes the query string is already encoded. I'm guessing it also doesn't encode characters like % in order to avoid breaking existing encodings. E.g., if I have "a b" encoded as "a%20b", UrlEncode("a%20b") gives "a%2520b" (equivalent to "a%20b", which is wrong), whereas UrlPathEncode just gives "a%20b" (which is right). – Tim Goodman Nov 29 '10 at 18:36
-
That said, I'm not when you'd use UrlPathEncode except if the only thing you want to encode is spaces (and they don't occur after a `?`). And it's not good that some of the documentation incorrectly claims that it encodes characters like `?`, `&` and `/` (http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.urlpathencode(v=VS.100).aspx) and some misleadingly makes it sound like it only differs from UrlEncode in how it encodes spaces (http://msdn.microsoft.com/en-us/library/system.web.httputility.urlpathencode.aspx) – Tim Goodman Nov 29 '10 at 18:59
-
2@Tim: there might be several `?` and who's to say which are to be encoded and which serve as separators? As to the space: in both cases the space is in the hash, so the presence or absence of a query-fragment shouldn't matter. And finally, it's inexcusable to corrupt an Uri as in the second example containing a %. The `UrlPathEncode` method is plain borked and should never be used. – Eamon Nerbonne May 31 '11 at 08:09
-
1I think my answer at http://stackoverflow.com/a/13993486/237091 may shed a little light on the intended usage of UrlEncode/UrlPathEncode. – Scott Stafford Feb 12 '14 at 02:55
-
I also ran into these issues in Java. It's dumbfounding to think that something so essential can be so convoluted in todays age. – Sebastian Patten Sep 26 '14 at 17:23
-
@alexangas: You just linked to precisely one of the borked methods :-) - kinda proves the point how confusing the .net api is here. – Eamon Nerbonne Oct 13 '14 at 12:36
-
@ScottStafford After I figured out what `UrlEncode` is for, I came here to post that but it looks like you've already done it. One thing to add is if you're using it outside a web application then you should use `System.Net.WebUtility` instead. – Pluto May 16 '18 at 23:47
-
Late to the party, but after a bit of research I now think there's two problems here. RFC 1866 defined that the query string of URLs should be application/x-www-form-urlencoded. So if you're encoding a URL, the space should be a "%20" BEFORE the "?", and a "+" when it's part of the query string (meaning real "+" characters become "%2b". In retrospect, that feels like someone made a mistake in the definition... – zippy72 Feb 04 '19 at 17:12
-
@zippy72 is right, the HTML standard specifies application/x-www-form-urlencoded for encoding after the "?". See "Mutate action URL" and "application/x-www-form-urlencoded serializer" in the HTML standard. These specify encoding space as "+" in the query string after the "?". – user281806 Jan 13 '22 at 22:27
HttpServerUtility.UrlEncode
will use HttpUtility.UrlEncode
internally. There is no specific difference. The reason for existence of Server.UrlEncode
is compatibility with classic ASP.

- 414,610
- 91
- 852
- 789
-
3As for what gets escaped. Internally it calls this function http://referencesource.microsoft.com/#System/net/System/Net/WebUtility.cs,8caf12e95a01d73b – Jeff Jan 26 '15 at 18:25
-
1For readers: Please look at Joel Muller's answer below. That is the most effective way to URL encode: http://stackoverflow.com/a/603962/190476 – Sudhanshu Mishra Apr 02 '16 at 06:40
Fast-forward almost 9 years since this was first asked, and in the world of .NET Core and .NET Standard, it seems the most common options we have for URL-encoding are WebUtility.UrlEncode (under System.Net
) and Uri.EscapeDataString. Judging by the most popular answer here and elsewhere, Uri.EscapeDataString appears to be preferable. But is it? I did some analysis to understand the differences and here's what I came up with:
WebUtility.UrlEncode
encodes space as+
;Uri.EscapeDataString
encodes it as%20
.Uri.EscapeDataString
percent-encodes!
,(
,)
, and*
;WebUtility.UrlEncode
does not.WebUtility.UrlEncode
percent-encodes~
;Uri.EscapeDataString
does not.Uri.EscapeDataString
throws aUriFormatException
on strings longer than 65,520 characters;WebUtility.UrlEncode
does not. (A more common problem than you might think, particularly when dealing with URL-encoded form data.)Uri.EscapeDataString
throws aUriFormatException
on the high surrogate characters;WebUtility.UrlEncode
does not. (That's a UTF-16 thing, probably a lot less common.)
For URL-encoding purposes, characters fit into one of 3 categories: unreserved (legal in a URL); reserved (legal in but has special meaning, so you might want to encode it); and everything else (must always be encoded).
According to the RFC, the reserved characters are: :/?#[]@!$&'()*+,;=
And the unreserved characters are alphanumeric and -._~
The Verdict
Uri.EscapeDataString clearly defines its mission: %-encode all reserved and illegal characters. WebUtility.UrlEncode is more ambiguous in both definition and implementation. Oddly, it encodes some reserved characters but not others (why parentheses and not brackets??), and stranger still it encodes that innocently unreserved ~
character.
Therefore, I concur with the popular advice - use Uri.EscapeDataString when possible, and understand that reserved characters like /
and ?
will get encoded. If you need to deal with potentially large strings, particularly with URL-encoded form content, you'll need to either fall back on WebUtility.UrlEncode and accept its quirks, or otherwise work around the problem.
EDIT: I've attempted to rectify ALL of the quirks mentioned above in Flurl via the Url.Encode
, Url.EncodeIllegalCharacters
, and Url.Decode
static methods. These are in the core package (which is tiny and doesn't include all the HTTP stuff), or feel free to rip them from the source. I welcome any comments/feedback you have on these.
Here's the code I used to discover which characters are encoded differently:
var diffs =
from i in Enumerable.Range(0, char.MaxValue + 1)
let c = (char)i
where !char.IsHighSurrogate(c)
let diff = new {
Original = c,
UrlEncode = WebUtility.UrlEncode(c.ToString()),
EscapeDataString = Uri.EscapeDataString(c.ToString()),
}
where diff.UrlEncode != diff.EscapeDataString
select diff;
foreach (var diff in diffs)
Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");

- 1
- 1

- 37,557
- 17
- 150
- 173
-
2
-
1Great job verifying the suggested solution on the modern .net framework. – Neowizard Jan 17 '18 at 13:35
-
2It should be mentioned that there are some differences between **WebUtility** and **HttpUtility**. **WebUtility** is using uppercase and **HttpUtility** is using lowercase for hexa entities. In addition **HttpUtility** was not included in old subset versions of .NET Framework "Client Profile". **WebUtility** is available from .NET Framework 4.0. – tibx Nov 20 '19 at 14:23
-
.NET Fiddle of the above code with `WebUtility.UrlEncode`, `Uri.EscapeDataString`, `Uri.EscapeUriString` and `HttpUtility.UrlPathEncode`: https://dotnetfiddle.net/Bo51qR – wensveen Oct 01 '20 at 07:52
-
As of at least .NET 4.8 (not sure where/when the change was introduced), `Uri.EscapeDataString("")` will correctly encode as 4 UTF-8 octects, showing that this method is currently Unicode-outside-of-BMP safe. Also, [MSDN now documents the maximum input length as 32k, not 64k](https://learn.microsoft.com/en-us/dotnet/api/system.uri.escapedatastring?view=netframework-4.8) (same for .NET Framework 4.8 and .NET Core+) – user2864740 Sep 08 '21 at 16:49
Keep in mind that you probably shouldn't be using either one of those methods. Microsoft's Anti-Cross Site Scripting Library includes replacements for HttpUtility.UrlEncode
and HttpUtility.HtmlEncode
that are both more standards-compliant, and more secure. As a bonus, you get a JavaScriptEncode
method as well.

- 40,302
- 20
- 199
- 253

- 28,324
- 9
- 63
- 88
-
After reading the documentation and FAQ on the link provided, I believe this answer is the best and most secure way to encode data! Thanks a ton for sharing this! – Sudhanshu Mishra Apr 02 '16 at 06:33
-
-
@EdwardBrey This is the latest version of Anti-Cross site scripting library: https://www.microsoft.com/en-au/download/details.aspx?id=28589 – Sudhanshu Mishra Jun 22 '17 at 00:23
-
Please include the answer in your answer. Broken links are not very helpful. I think you're hinting at `System.Web.Security.AntiXss.AntiXssEncoder.UrlEncode` which is *yet another* method of encoding. – wensveen Oct 01 '20 at 08:16
-
It looks like the output of `AntiXssEncoder.UrlEncode` is equal to that of `Uri.EscapeDataString` but the code doesn't depend on `Uri.EscapeDataString` as far as I can tell. – wensveen Oct 01 '20 at 10:31
-
1
Server.UrlEncode() is there to provide backward compatibility with Classic ASP,
Server.UrlEncode(str);
Is equivalent to:
HttpUtility.UrlEncode(str, Response.ContentEncoding);

- 807,428
- 183
- 922
- 838
The same, Server.UrlEncode()
calls HttpUtility.UrlEncode()

- 8,252
- 7
- 42
- 60

- 22,388
- 8
- 62
- 82