C#是否有与JavaScript的encodeURIComponent()相当的等效功能?

163

在JavaScript中:

encodeURIComponent("©√") == "%C2%A9%E2%88%9A"

在C#应用程序中是否有相应的功能?我使用以下方法来转义HTML字符:

txtOut.Text = Regex.Replace(txtIn.Text, @"[\u0080-\uFFFF]",
    m => @"&#" + ((int)m.Value[0]).ToString() + ";");

但我不确定如何将匹配项转换为JS使用的正确十六进制格式。例如,以下代码:

txtOut.Text = Regex.Replace(txtIn.Text, @"[\u0080-\uFFFF]",
    m => @"%" + String.Format("{0:x}", ((int)m.Value[0])));
对于字符串"©√",返回的结果是"%a9%221a",而不是"%C2%A9%E2%88%9A"。看起来我需要将字符串拆分为字节或其他内容。

编辑:这是用于Windows应用程序的,只能使用 System.Web 中提供的这些项:AspNetHostingPermissionAspNetHostingPermissionAttributeAspNetHostingPermissionLevel

7个回答

279

Uri.EscapeDataStringHttpUtility.UrlEncode 是转义 URL 字符串的正确方法。

以字符串 "Stack Overflow" 为例:

  • HttpUtility.UrlEncode("Stack Overflow") --> "Stack+Overflow"

  • Uri.EscapeUriString("Stack Overflow") --> "Stack%20Overflow"

  • Uri.EscapeDataString("Stack + Overflow") --> 同时将 "+" 编码为 "%2b" ----> Stack%20%2B%20%20Overflow

只有最后一种方法在作为 URL 的实际部分时才是正确的(而不是查询字符串参数值的一部分)。


64
与 encodeURIComponent() 不同,Uri.EscapeUriString() 不会将“+”编码为“%2b”。建议使用 Uri.EscapeDataString() 替代。 - jwaliszko
6
使用WebUtility代替HttpUtility,避免引用System.Web。HttpUtility在.NET Core中不存在。 - Steven De Kock
3
@Steve,你会考虑将最后一段加粗吗?它似乎是这个页面上最重要的内容,需要更多的可见性。 - Timo
还可以查看此答案,了解Uri.EscapeUriString和Uri.EscapeDataString之间的区别的更多解释:https://dev59.com/Zm855IYBdhLWcg3wVi23 - Jason
感谢Steve提供了这个出色的答案,以及Tim提供的编辑版本。在漫长的搜索之后,这确实起到了很好的作用并节约了我的神经。对于你们所有经常为这个非常有用的平台做出贡献的人,我说声谢谢! - omostan
显示剩余5条评论

22

HttpUtility.HtmlEncode / Decode
HttpUtility.UrlEncode / Decode

如果您的项目中没有 System.Web 程序集,可以添加引用。


我应该更加具体说明:这是为 Windows 应用程序而设计的,在 System.Web 中仅有可用的项目包括:AspNetHostingPermission、AspNetHostingPermissionAttribute 和 AspNetHostingPermissionLevel。 - travis
5
您可以将对 System.Web 程序集的引用添加进来。 - David Thibault
2
HtmlEncoding是完全不同的东西。UrlEncode是一个毫无意义的API,永远不应该被使用。对整个URL进行编码是没有意义的(除非你真的想将其值编码以用作参数-但这不是它的作用)。编码/转义的重点在于传达保留字符应该通过而不具有其通常的含义(例如,?标识查询,或&分隔查询参数)。这需要UrlEncode没有也不能有的知识。 - Brandon Paddock

20

我尝试创建 C# 版本的与 JavaScript 的 encodeURIComponent 完全兼容的函数,经过 4 小时的实验后,我发现了以下代码:

C# 代码:

string a = "!@#$%^&*()_+ some text here али мамедов баку";
a = System.Web.HttpUtility.UrlEncode(a);
a = a.Replace("+", "%20");

结果为: !%40%23%24%25%5e%26*()_%2b%20some%20text%20here%20%d0%b0%d0%bb%d0%b8%20%d0%bc%d0%b0%d0%bc%d0%b5%d0%b4%d0%be%d0%b2%20%d0%b1%d0%b0%d0%ba%d1%83

使用JavaScript的decodeURIComponent()函数进行解码后,您将得到以下结果: !@#$%^&*()_+ some text here али мамедов баку

感谢关注。


2
可以使用Uri.EscapeDataString("!@#$%^&*()_+ some text here али мамедов баку")来代替,虽然原本的代码也能正常工作。 - mklement0
1
实际上,Uri.EscapeDataString 对字符 '(' 和 ')' 进行编码,而 HttpUtility.UrlEncode 则不会。 - Øystein Kolsrud

14

System.Uri.EscapeUriString() 没有任何作用,但 System.Uri.EscapeDataString() 对我有用。


10

对于 Windows Store 应用程序,您将不会使用 HttpUtility。相反,您需要使用以下方法:

对于 URI,在“?”之前:

  • System.Uri.EscapeUriString("example.com/Stack Overflow++?")
    • -> "example.com/Stack%20Overflow++?"

对于 URI 查询名称或值,在“?”之后:

  • System.Uri.EscapeDataString("Stack Overflow++")
    • -> "Stack%20Overflow%2B%2B"

对于 x-www-form-urlencoded 查询名称或值,在 POST 内容中:

  • System.Net.WebUtility.UrlEncode("Stack Overflow++")
    • -> "Stack+Overflow%2B%2B"

10
尝试使用 Server.UrlEncode()System.Web.HttpUtility.UrlEncode(),在没有访问 Server 对象的情况下使用。您也可以使用 System.Uri.EscapeUriString() 来避免添加对 System.Web 程序集的引用。

1
Uri.EscapeUriString() 对我没有起作用,但是我能够使用 Uri.EscapeDataString() 正确地对字符串进行 URL 编码。 - Toland Hon
4
@TolandHon:确实。这是因为Uri.EscapeUriString()对应JavaScript的encodeURI()——它将保留URI保留字符,例如 /&等(加上#),而正如你发现的那样,Uri.EscapeDataString()才对应JavaScript的encodeURIComponent() - mklement0

6
您可以在System.Web命名空间中使用Server对象。
其中包括Server.UrlEncode、Server.UrlDecode、Server.HtmlEncode和Server.HtmlDecode。
编辑:发布者补充说明这是一个Windows应用程序,而不是像人们所认为的Web应用程序。上述项目将从System.Web内的HttpUtility类中提供,该类必须作为项目的引用添加。

1
服务器对象无法从 Windows 应用程序访问。 - travis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接