17


I need to pass special characters like #,! etc in URL to Facebook,Twitter and such social sites. For that I am replacing such characters with URL Escape Codes.

 return valToEncode.Replace("!", "%21").Replace("#", "%23")
   .Replace("$", "%24").Replace("&", "%26")
   .Replace("'", "%27").Replace("(", "%28")
   .Replace(")", "%29").Replace("*", "%2A");

It works for me, but I want to do it more efficiently.Is there any other way to escape such characters? I tried with Server.URLEncode() but Facebook doesn't render it.

Thanks in advance,
Priya

David Lee
  • 811
  • 7
  • 19
Priya
  • 1,375
  • 8
  • 21
  • 45

4 Answers4

44

You should use the **Uri.EscapeDataString** method if you want to have compatibility with RFC3986 standard, where percent-encoding is defined.

For example spaces always will be encoded as %20 character:

var result = Uri.EscapeDataString("a q");
// result == "a%20q"

while for example usage of HttpUtility.UrlEncode (which is by the way internally used by HttpServerUtility.UrlEncode) returns + character:

var result = HttpUtility.UrlEncode("a q") 
// result == "a+q"

What's more, the behavior of Uri.EscapeDataString is compatible with client side encodeURIComponent javascript method (except the case sensitivity, but RFC3986 says it is irrelevant).

Community
  • 1
  • 1
jwaliszko
  • 16,942
  • 22
  • 92
  • 158
  • 1
    It also depends on whether FB, Twitter etc. has IRI IDN parsing enabled. Twitter 1.1 for instance has this, so characters like eg. '!' has to be encoded as well ("%21") – mhoff Mar 21 '14 at 09:31
5

For those still searching, Thomas B provided a great one-liner for this.

Regex.Replace(Uri.EscapeDataString(s), "[\!*\'\(\)]", Function(m) Uri.HexEscape(Convert.ToChar(m.Value(0).ToString())))

Found in the comments under this excellent answer which also provides a sound solution to the problem.

The behavior for Uri.EscapeDataString changes in .Net 4.5.

The list of reserved and unreserved characters now supports RFC 3986.

See Application Compatibility in the .NET Framework 4.5.

Also note the specific reserved characters for RFC 3986. I haven't tested either function extensively nor have I taken the time to study RFC 2396 so I can only assume that Andrew and Thomas are using a subset of the reserved characters because that subset reflects the difference between RFC 2396 and RFC 3986 and the remaining characters are already handled by Uri.EscapeDataString.

Community
  • 1
  • 1
Rich C
  • 802
  • 2
  • 13
  • 33
3

This code will "PercentEncode" per rfc 3986. HttpUtility.EncodeUrl does not account for many characters ('!', '*', '(', ')') and does not upper case the hex letters following the % character.

public static string PercentEncode(string value)  
{  
    StringBuilder retval = new StringBuilder();  
    foreach (char c in value)  
    {   
        if ((c >= 48 && c <= 57) || //0-9  
            (c >= 65 && c <= 90) || //a-z  
            (c >= 97 && c <= 122) || //A-Z                    
            (c == 45 || c == 46 || c == 95 || c == 126)) // period, hyphen, underscore, tilde  
        {  
            retval.Append(c);  
        }  
        else  
        {  
            retval.AppendFormat("%{0:X2}", ((byte)c));  
        }  
    }  
    return retval.ToString();  
}  
  • 2
    Welcome to SO. Please understand: this answer is really **bad** for two reasons: A) no formatting whatsoever - there is a lot of help to understand how to format, and even a **preview** function. Use that B) "code only answers" are discourages. Always consider having some explanations. – GhostCat Jun 20 '17 at 12:58
  • 3
    Thanks, I've edited my answer based on your feedback. – user8166689 Jun 20 '17 at 15:10
2

Use System.Web.HttpUtility.UrlEncode or System.Net.WebUtility.UrlEncode instead of forming it manually.

I4V
  • 34,891
  • 6
  • 67
  • 79