Martin Brown
Martin Brown

Reputation: 25330

How do you UrlEncode without using System.Web?

I am trying to write a windows client application that calls a web site for data. To keep the install to a minimum I am trying only use dlls in the .NET Framework Client Profile. Trouble is that I need to UrlEncode some parameters, is there an easy way to do this without importing System.Web.dll which is not part of the Client Pofile?

Upvotes: 319

Views: 228386

Answers (9)

k1dfr0std
k1dfr0std

Reputation: 570

I've been forced to use .NET 4.0 for some of the projects I've built, and due to this, neither WebUtility nor HttpUtility will contain these. I used the Uri.EscapeDataString() method which works really well, but I did not like the fact it didn't encode all standard special characters (meaning ! "#$%&'()*+,-./:;<=>?@[\]^_`{|}~) in one go. I also deal more with Visual Basic than C#, so I do not know for sure what it would take to convert the following, but it works fantastic for my basic needs.

I won't be dealing with any UTF-8 formatted strings with this as it's only used for some very basic text manipulation and has served me well so far. It will not parse out line breaks in any fashion (the text I'm manipulating won't have them), and you have to process the % sign first to prevent it from ruining the encoding of the rest of the symbols. A bit garish, but it works.

Function EncodeURL(ByVal DecodedString As String) As String

  DecodedString = Replace(DecodedString, "%", "%25", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, " ", "%20", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "!", "%21", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, """", "%22", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "#", "%23", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "$", "%24", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "&", "%26", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "'", "%27", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "(", "%28", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ")", "%29", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "*", "%2A", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "+", "%2B", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ",", "%2C", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "-", "%2D", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ".", "%2E", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "/", "%2F", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ":", "%3A", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ";", "%3B", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "<", "%3C", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "=", "%3D", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, ">", "%3E", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "?", "%3F", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "@", "%40", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "[", "%5B", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "\", "%5C", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "]", "%5D", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "^", "%5E", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "_", "%5F", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "`", "%60", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "{", "%7B", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "|", "%7C", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "}", "%7D", 1, vbTextCompare)
  DecodedString = Replace(DecodedString, "~", "%7E", 1, vbTextCompare)

  EncodeURL = DecodedString

End Function

Input:

! "#$%&'()*+,-./:;<=>?@[]^_`{|}~

Output

%21%20%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E%5F%60%7B%7C%7D%7E

Upvotes: 0

Thymine
Thymine

Reputation: 9205

In .Net 4.5+ use WebUtility

Just for formatting I'm submitting this as an answer.

Couldn't find any good examples comparing them so:

string testString = "http://test# space 123/text?var=val&another=two";
Console.WriteLine("UrlEncode:         " + System.Web.HttpUtility.UrlEncode(testString));
Console.WriteLine("EscapeUriString:   " + Uri.EscapeUriString(testString));
Console.WriteLine("EscapeDataString:  " + Uri.EscapeDataString(testString));
Console.WriteLine("EscapeDataReplace: " + Uri.EscapeDataString(testString).Replace("%20", "+"));

Console.WriteLine("HtmlEncode:        " + System.Web.HttpUtility.HtmlEncode(testString));
Console.WriteLine("UrlPathEncode:     " + System.Web.HttpUtility.UrlPathEncode(testString));

//.Net 4.0+
Console.WriteLine("WebUtility.HtmlEncode: " + WebUtility.HtmlEncode(testString));
//.Net 4.5+
Console.WriteLine("WebUtility.UrlEncode:  " + WebUtility.UrlEncode(testString));

Outputs:

UrlEncode:             http%3a%2f%2ftest%23+space+123%2ftext%3fvar%3dval%26another%3dtwo
EscapeUriString:       http://test#%20space%20123/text?var=val&another=two
EscapeDataString:      http%3A%2F%2Ftest%23%20space%20123%2Ftext%3Fvar%3Dval%26another%3Dtwo
EscapeDataReplace:     http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

HtmlEncode:            http://test# space 123/text?var=val&amp;another=two
UrlPathEncode:         http://test#%20space%20123/text?var=val&another=two

//.Net 4.0+
WebUtility.HtmlEncode: http://test# space 123/text?var=val&amp;another=two
//.Net 4.5+
WebUtility.UrlEncode:  http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

In .Net 4.5+ use WebUtility.UrlEncode

This appears to replicate HttpUtility.UrlEncode (pre-v4.0) for the more common characters:
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
Note: EscapeUriString will keep a valid uri string, which causes it to use as many plaintext characters as possible.

See this answer for a Table Comparing the various Encodings:
https://stackoverflow.com/a/11236038/555798

Line Breaks All of them listed here (other than HttpUtility.HtmlEncode) will convert "\n\r" into %0a%0d or %0A%0D

Please feel free to edit this and add new characters to my test string, or leave them in the comments and I'll edit it.

Upvotes: 264

ToddBFisher
ToddBFisher

Reputation: 11610

System.Uri.EscapeUriString() can be problematic with certain characters, for me it was a number / pound '#' sign in the string.

If that is an issue for you, try:

System.Uri.EscapeDataString() //Works excellent with individual values

Here is a SO question answer that explains the difference:

What's the difference between EscapeUriString and EscapeDataString?

and recommends to use Uri.EscapeDataString() in any aspect.

Upvotes: 325

Aaron Qiu
Aaron Qiu

Reputation: 29

To UrlEncode without using System.Web:

String s = System.Net.WebUtility.UrlEncode(str);
//fix some different between WebUtility.UrlEncode and HttpUtility.UrlEncode
s = Regex.Replace(s, "(%[0-9A-F]{2})", c => c.Value.ToLowerInvariant());

more details: https://www.samnoble.co.uk/2014/05/21/beware-webutility-urlencode-vs-httputility-urlencode/

Upvotes: 0

Elmue
Elmue

Reputation: 8178

The answers here are very good, but still insufficient for me.

I wrote a small loop that compares Uri.EscapeUriString with Uri.EscapeDataString for all characters from 0 to 255.

NOTE: Both functions have the built-in intelligence that characters above 0x80 are first UTF-8 encoded and then percent encoded.

Here is the result:

******* Different *******

'#' -> Uri "#" Data "%23"
'$' -> Uri "$" Data "%24"
'&' -> Uri "&" Data "%26"
'+' -> Uri "+" Data "%2B"
',' -> Uri "," Data "%2C"
'/' -> Uri "/" Data "%2F"
':' -> Uri ":" Data "%3A"
';' -> Uri ";" Data "%3B"
'=' -> Uri "=" Data "%3D"
'?' -> Uri "?" Data "%3F"
'@' -> Uri "@" Data "%40"


******* Not escaped *******

'!' -> Uri "!" Data "!"
''' -> Uri "'" Data "'"
'(' -> Uri "(" Data "("
')' -> Uri ")" Data ")"
'*' -> Uri "*" Data "*"
'-' -> Uri "-" Data "-"
'.' -> Uri "." Data "."
'_' -> Uri "_" Data "_"
'~' -> Uri "~" Data "~"

'0' -> Uri "0" Data "0"
.....
'9' -> Uri "9" Data "9"

'A' -> Uri "A" Data "A"
......
'Z' -> Uri "Z" Data "Z"

'a' -> Uri "a" Data "a"
.....
'z' -> Uri "z" Data "z"

******* UTF 8 *******

.....
'Ò' -> Uri "%C3%92" Data "%C3%92"
'Ó' -> Uri "%C3%93" Data "%C3%93"
'Ô' -> Uri "%C3%94" Data "%C3%94"
'Õ' -> Uri "%C3%95" Data "%C3%95"
'Ö' -> Uri "%C3%96" Data "%C3%96"
.....

EscapeUriString is to be used to encode URLs, while EscapeDataString is to be used to encode for example the content of a Cookie, because Cookie data must not contain the reserved characters '=' and ';'.

Upvotes: 23

user3105093
user3105093

Reputation: 31

System.Net.WebUtility.HtmlDecode

Upvotes: -3

Darin Dimitrov
Darin Dimitrov

Reputation: 1039438

Here's an example of sending a POST request that properly encodes parameters using application/x-www-form-urlencoded content type:

using (var client = new WebClient())
{
    var values = new NameValueCollection
    {
        { "param1", "value1" },
        { "param2", "value2" },
    };
    var result = client.UploadValues("http://foo.com", values);
}

Upvotes: 8

Matthew Manela
Matthew Manela

Reputation: 16762

You can use

Uri.EscapeUriString (see http://msdn.microsoft.com/en-us/library/system.uri.escapeuristring.aspx)

Upvotes: 54

Sprague
Sprague

Reputation: 1638

There's a client profile usable version, System.Net.WebUtility class, present in client profile System.dll. Here's the MSDN Link:

WebUtility

Upvotes: 17

Related Questions