如何在不使用System.Web的情况下进行UrlEncode?


310

我试图编写一个Windows客户端应用程序,该应用程序调用网站以获取数据。为了尽量减少安装,我尝试仅使用.NET Framework Client Profile中的dll。问题是我需要对一些参数进行UrlEncode编码,是否有一种简单的方法可以在不导入不属于客户端Pofile的System.Web.dll的情况下执行此操作?


您能否说明如何执行对网站的呼叫?也许那里可以做些事情。
Darin Dimitrov

出于好奇,您如何在不使用System.Web的情况下调用网站获取数据?
Patrick McDonald

@Patrick,他可能正在使用WebRequestWebClient。这就是我询问此特定代码的原因,因为可以对正确的url编码数据进行某些操作。
Darin Dimitrov

1
我正在使用System.Net.WebRequest对象。然后,我调用GetRequestStream并将Post参数写到流中。我还将ContentType设置为“ application / x-www-form-urlencoded”。
马丁·布朗

1
当然,如果我正在执行GET请求并将参数附加到URL,则同样适用。
马丁·布朗

Answers:


317

System.Uri.EscapeUriString() 某些字符可能有问题,对我而言,它是字符串中的数字/磅“#”符号。

如果这对您来说是一个问题,请尝试:

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

这是一个SO答案,解释了区别:

EscapeUriString和EscapeDataString有什么区别?

并建议Uri.EscapeDataString()在任何方面使用。


1
错误:blogs.msdn.com/b/yangxind/archive/2006/11/09/…加号会出现问题,因为它们不会被未编码。
克里斯·韦伯

7
那篇博客文章有点老了,我只有一个完整的URL“ Uri Escaped”,所有空格都变成了%20,因此我认为他们已将其修复。我正在使用.Net 4.5。
罗迪

如果要为POST操作准备数据,EscapeDataString也不支持很长的字符串。 stackoverflow.com/questions/6695208/…–
布朗·戴维斯

Uri.EscapeUriString确实确实存在很大问题,因此不应该使用它,因为它试图做一些实际上不可能始终如一地做的事情(转义完整的URI)。有关详细说明,请参见此答案
利文(Livven)

也是''空格字符。
Waqas Shabbir

252

在.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字符串,这将导致它使用尽可能多的纯文本字符。

请参阅此答案以获取比较各种编码的表格:https :
//stackoverflow.com/a/11236038/555798

换行符 此处列出的所有字符(除外HttpUtility.HtmlEncode)将转换"\n\r"%0a%0d%0A%0D

请随时对其进行编辑,并将新字符添加到我的测试字符串中,或​​者将其保留在注释中,然后我将对其进行编辑。


就我而言,我不得不使用EscapeDataString而不是EscapeUriString编码回车和换行符,而这需要由EscapeDataString
David O'Meara

1
更多示例,您可以根据需要提供自己的测试用例。这是运行它的示例以及其他编码方法,显示了不同点dotnetfiddle.net/12IFw1
Maslow

3
WebUtility.UrlEncode()和WebUtility.UrlDecode()为4.5+。它们在4.0中不存在。
Derek Kalweit

msdn说:“通用Windows平台:从4.5开始可用,.NET Framework:从4.0开始可用” ...
Thymine

54

您可以使用

Uri.EscapeUriString(请参阅http://msdn.microsoft.com/zh-cn/library/system.uri.escapeuristring.aspx


这和EscapeDataString有区别吗?
马丁·布朗

3
您要使用EscapeUriString。EscapeUriString将尝试对整个网址(包括http://部分)进行编码,而EscapeUriString则了解应实际编码的部分
Matthew Manela 2010年

1
我知道,因此在这种情况下,我可能想要EscapeDataString,因为我可能希望将URL作为get参数传递。我将在此实例中附加到URL。
马丁·布朗

5
@MatthewManela我很确定您的Oct1注释应读为EscapeDataString将尝试编码...
Maslow

不要使用Uri.EscapeUriString。它不能“理解”应该对哪些部分进行编码,而只是在做某些事情(转义完整的URI)时被误导了,这实际上是不可能始终如一地进行的。请参阅此答案以获取详细说明。
利文(Livven)2016年

20

这里的答案很好,但对我来说仍然不够。

我写了一个小循环,比较Uri.EscapeUriStringUri.EscapeDataString0到255之间的所有字符。

注意:这两个功能都具有内置的智能功能,即首先对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数据中不得包含保留字符'='';'


很好的分析和分解,非常有帮助。如果有人拥有或知道性能基准测试(比较所有三种方法),那也很高兴
Shaun Wilson

这是一个很好的分析,并且有一个好处是您不应该使用Uri.EscapeUriString,因为转义完整的URI不可能始终如一。请参阅此答案以获取详细说明。
利文(Livven)2016年

16

客户端配置文件System.dll中存在一个客户端配置文件可用版本System.Net.WebUtility类。这是MSDN链接:

Web实用程序


我会注意到,该类的帮助页面上专门显示“提供处理Web请求时用于编码和解码URL的方法”。因此可能只是他们没有很好地命名方法。
詹姆斯·怀特

说得好点,为什么你不投票给兄弟一个;)这次失败的投票困扰了我两年!JK ...但是说实话,这可能就是我发布链接的原因,不幸的是,我因Microsoft文档中的错误而名声大振...
Sprague 2012年

11
似乎UrlEncode和UrlDecode仅在.Net 4.5版本中添加到WebUtility。
马丁·布朗

8

这是发送POST请求的示例,该请求使用application/x-www-form-urlencoded内容类型正确编码了参数 :

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


-3
System.Net.WebUtility.HtmlDecode

WebUtility类提供了在处理Web请求时用于编码和解码URL的方法。它执行与HttpUtility相同的操作,但不在System.Web名称空间中
Alexandru

3
这是错误的,因为它是HtmlDecodes而不是UrlEncode像询问的问题。甚至HtmlEncode也将是错误的,因为HTML编码不同于URL编码。
马丁·布朗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.