URL 在 vb.net 中编码数据 RFC-3986

URL encode data RFC-3986 in vb.net

如何将此代码转换为 VB?

/// <summary>
/// Returns URL encoded version of input data according to RFC-3986
/// </summary>
/// <param name="data">String to be URL-encoded</param>
/// <returns>URL encoded version of input data</returns>
public static string UrlEncode(string data)
{
    StringBuilder encoded = new StringBuilder();
    foreach (char symbol in Encoding.UTF8.GetBytes(data))
    {
        if (ValidUrlCharacters.IndexOf(symbol) != -1)
        {
            encoded.Append(symbol);
        }
        else
        {
            encoded.Append("%").Append(string.Format(CultureInfo.InvariantCulture, "{0:X2}", (int)symbol));
        }
    }
    return encoded.ToString();
}

我试过一个代码转换器,但它出错了

Error BC32007 'Byte' values cannot be converted to 'Char'. Use 'Microsoft.VisualBasic.ChrW' to interpret a numeric value as a Unicode character or first convert it to 'String' to produce a digit.

提前致谢

一个 String 已经是一个 IEnumerable(Of Char),所以不需要对 String 做任何事情。

For Each symbol In data

这也适用于 C#。您拥有的代码只是将所有字符转换为 bytes,然后再次转换回 chars,这是毫无意义的。

您可能使用的转换器不是对可能性有深入了解的程序员。它只是关键字和语法的浅层映射器。 它给了你下面这行,对吧?

For Each symbol As Char In Encoding.UTF8.GetBytes(data)

这导致了您提到的错误。 @jmcilhinney 已经给了你正确答案(又名程序员会怎么做)这实际上是一种解决方法,因为要正确编写此代码可以避免使用 GetBytes() 结果作为 Char 可枚举。

但这里有另一种解决方案,它可以解决确切的错误消息。如果情况无法避免,您可以使用它。


...
Imports System.Text
Imports System.Globalization
Imports Microsoft.VisualBasic
...

Public Shared Function UrlEncode(ByVal data As String) As String
   Dim encoded As StringBuilder = New StringBuilder()

   ' you get Bytes here...
   For Each dataByte As Byte In Encoding.UTF8.GetBytes(data)
            
      ' ... and convert to Char here
      Dim symbol = ChrW(dataByte)

      If ValidUrlCharacters.IndexOf(symbol) <> -1 Then
         encoded.Append(symbol)
      Else
         encoded.Append("%").Append(String.Format(CultureInfo.InvariantCulture, "{0:X2}", Microsoft.VisualBasic.AscW(symbol)))
      End If
   Next

   Return encoded.ToString()
End Function

编辑:

P.S.: 你为什么在字符串中使用 CultureInfo.Invariant 到十六进制格式?会有什么不同?以下似乎就足够了:

encoded.Append("%").Append(Microsoft.VisualBasic.AscW(symbol).ToString("X2"))

编辑2:

正如@Heinzi 所指出的,@jmcilhinney 的回答是不正确的。 用我的! :)