C# 在 URL 中发送特殊字符之前的百分比编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16186042/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Percentage Encoding of special characters before sending it in the URL
提问by Priya
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.
我需要传递特殊字符,如 #,! 等在指向 Facebook、Twitter 和此类社交网站的 URL 中。为此,我将用 URL 转义码替换这些字符。
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.
它对我有用,但我想更有效地做到这一点。还有其他方法可以转义这些字符吗?我尝试使用Server.URLEncode()但 Facebook 没有呈现它。
Thanks in advance,
Priya
提前致谢,
普里亚
回答by I4V
Use System.Web.HttpUtility.UrlEncodeor System.Net.WebUtility.UrlEncodeinstead of forming it manually.
使用System.Web.HttpUtility.UrlEncode或System.Net.WebUtility.UrlEncode代替手动形成。
回答by jwaliszko
You should use the Uri.EscapeDataStringmethod if you want to have compatibility with RFC3986standard, where percent-encoding is defined.
如果您想与RFC3986标准兼容,您应该使用Uri.EscapeDataString方法,其中定义了百分比编码。
For example spaces always will be encoded as %20character:
例如,空格总是被编码为%20字符:
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:
而例如使用HttpUtility.UrlEncode(这是由内部使用的方式HttpServerUtility.UrlEncode)返回+字符:
var result = HttpUtility.UrlEncode("a q")
// result == "a+q"
What's more, the behavior of Uri.EscapeDataStringis compatible with client side encodeURIComponentjavascript method (except the case sensitivity, but RFC3986 says it is irrelevant).
更重要的是, 的行为Uri.EscapeDataString与客户端encodeURIComponentjavascript 方法兼容(区分大小写除外,但 RFC3986 表示它无关紧要)。
回答by Rich C
For those still searching, Thomas B provided a great one-liner for this.
对于那些仍在寻找的人,Thomas B 为此提供了一个很好的单线。
Regex.Replace(Uri.EscapeDataString(s), "[\!*\'\(\)]", Function(m) Uri.HexEscape(Convert.ToChar(m.Value(0).ToString())))
Found in the comments under this excellent answerwhich also provides a sound solution to the problem.
在此优秀答案下的评论中找到,该答案也为该问题提供了合理的解决方案。
The behavior for Uri.EscapeDataStringchanges in .Net 4.5.
Uri.EscapeDataString.Net 4.5 中更改的行为。
The list of reserved and unreserved characters now supports RFC 3986.
保留和非保留字符列表现在支持 RFC 3986。
See Application Compatibility in the .NET Framework 4.5.
请参阅.NET Framework 4.5 中的应用程序兼容性。
Also note the specific reserved charactersfor 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.
还要注意RFC 3986的特定保留字符。我没有广泛测试这两个函数,也没有花时间研究 RFC 2396,所以我只能假设 Andrew 和 Thomas 使用的是保留字符的子集,因为该子集反映了RFC 2396 和 RFC 3986 之间的差异,其余字符已由Uri.EscapeDataString.
回答by user8166689
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.
此代码将按照 rfc 3986 进行“PercentEncode”。HttpUtility.EncodeUrl 不考虑许多字符('!'、'*'、'('、')'),并且不会将 % 字符后面的十六进制字母大写。
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();
}

