我正在尝试编写一个Windows客户端应用程序,调用网站上的数据。为了使安装最小化,我尝试仅使用.NET Framework客户端配置文件中的dll。问题是我需要对一些参数进行UrlEncode,有没有一种简单的方法可以做到这一点,而不需要导入System.Web.dll,因为它不是客户端配置文件的一部分?
我正在尝试编写一个Windows客户端应用程序,调用网站上的数据。为了使安装最小化,我尝试仅使用.NET Framework客户端配置文件中的dll。问题是我需要对一些参数进行UrlEncode,有没有一种简单的方法可以做到这一点,而不需要导入System.Web.dll,因为它不是客户端配置文件的一部分?
System.Uri.EscapeDataString()
在处理某些字符时可能会出现问题,对我来说是字符串中的数字或井号“#”。
如果这对你也是一个问题,请尝试使用:
System.Uri.EscapeDataString() //Works excellent with individual values
这是一个SO问题的答案,解释了EscapeUriString和EscapeDataString之间的区别:
什么是EscapeUriString和EscapeDataString之间的区别?
并推荐在任何方面都使用Uri.EscapeDataString()
。
在 .Net 4.5+ 中请使用WebUtility
这里只是为了格式化而提交这个答案。
没有找到任何好的例子来比较它们,所以:
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));
输出:
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&another=two
UrlPathEncode: http://test#%20space%20123/text?var=val&another=two
//.Net 4.0+
WebUtility.HtmlEncode: http://test# space 123/text?var=val&another=two
//.Net 4.5+
WebUtility.UrlEncode: http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo
在 .Net 4.5+ 中,请使用 WebUtility
.UrlEncode
这似乎复制了更常见字符的 HttpUtility.UrlEncode
(早于 v4.0):Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
EscapeUriString
会保留有效的 URI 字符串,这会导致它尽可能使用多个纯文本字符。HttpUtility.HtmlEncode
外,所有列在此处的方法都将把 "\n\r"
转换为 %0a%0d
或 %0A%0D
请随意编辑并向我的测试字符串添加新字符,或将它们留在评论中,我会编辑它。EscapeDataString
而不是EscapeUriString
,因为我们对回车和换行进行了编码,这需要EscapeDataString
执行更积极的转义。 - David O'Meara您可以使用 Uri.EscapeUriString(参见http://msdn.microsoft.com/en-us/library/system.uri.escapeuristring.aspx)。
Uri.EscapeUriString
。它并不“理解”哪些部分应该被编码,它只是一种误导性的尝试去做一些(转义完整的URI),这实际上是不可能始终如一地做到的。请参见此答案以获取详细说明。 - Livven这里的答案非常好,但对我来说仍然不够。
我编写了一个小循环,比较了从0到255的所有字符的Uri.EscapeUriString
和Uri.EscapeDataString
。
注意:两个函数都具有内置智能,即对于大于0x80的字符,先进行UTF-8编码,然后进行百分号编码。
以下是结果:
******* 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
用于对URL进行编码,而 EscapeDataString
则用于对Cookie内容进行编码,因为Cookie数据不得包含保留字符'='
和';'
。
在客户端框架(System.dll)中,存在一个可用的客户端配置文件版本(System.Net.WebUtility类)。以下是 MSDN 链接:
application/x-www-form-urlencoded
内容类型正确编码参数的发送POST请求的示例:using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "param1", "value1" },
{ "param2", "value2" },
};
var result = client.UploadValues("http://foo.com", values);
}
我被迫在一些项目中使用.NET 4.0,因此,WebUtility
和HttpUtility
都不包含这些内容。我使用了Uri.EscapeDataString()
方法,它的效果非常好,但我不喜欢它没有一次性编码所有标准特殊字符(意味着! "#$%&'()*+,-./:;<=>?@[\]^_`{|}~
)。我更多地处理Visual Basic而不是C#,所以我不确定转换以下内容需要什么,但它对我的基本需求非常有效。
我不会处理任何UTF-8格式的字符串,因为它仅用于一些非常基本的文本操作,并且到目前为止已经为我服务得很好。它不会以任何方式解析出换行符(我要操作的文本不会有它们),并且您必须首先处理%
符号,以防止它破坏其余符号的编码。有点丑陋,但它有效。
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
输入:
! "#$%&'()*+,-./:;<=>?@[]^_`{|}~
输出
%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
Dictionary<char, string>
来定义每个要替换的字符到替换文本的映射(例如,'!'
→ "21"
)来使这段代码更易于管理和高效。然后枚举DecodedString
并将替换文本(如果在Dictionary<,>
中找到输入char
)或者输入char
附加到StringBuilder
中。另外,由于字符被编码为十六进制ASCII值,你也可以使用HashSet<char>
、switch
或简单的范围(例如,0x23 ≤ c ≤ 0x2C
等)来定义要替换的char
,然后发出(byte) c
。 - Lance U. Matthews代码样式
文本中的所有符号和正确的VB.NET语言格式。非常感谢您的帮助 - 我未来的帖子将有更好的格式! - k1dfr0stdlang-vbnet
语言提示来指定VB.NET语言,但是还有其他别名可以使用(例如lang-vb
)以及标签名称(例如vb.net
),如果它有相关的语言代码。请参见“什么是语法高亮,它是如何工作的?”这个答案。 - Lance U. Matthews如何在不使用 System.Web 的情况下进行 UrlEncode:
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());
System.Net.WebUtility.HtmlDecode
WebRequest
或WebClient
。这就是我问及这段特定代码的原因,因为有些事情可以正确地对数据进行URL编码。 - Darin Dimitrov