Search code examples
c#vb.neturlencodecode-conversion

URL encode data RFC-3986 in vb.net


How do I convert this code to 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();
}

I have tried a code converter but it errors with

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.

Thanks In Advance


Solution

  • A converter you may used is not a programmer with deep knowledge of possibilities. It just a shallow mapper of keywords and syntax. It gave you the following line, right?

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

    This resulted in the error you mentioned. @jmcilhinney already gave you the correct answer (aka how a programmer would do it) which is actually a workaround, because to program this code correctly avoids using GetBytes() result as a Char enumerable.

    But here is an other solution which solves the exact error message instead. In cases the situation not avoidable you may use this.

    
    ...
    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
    

    EDIT:

    P.S.: Why are you using CultureInfo.Invariant in string to hex format at all? What difference will it make? The following seems to be enough:

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

    EDIT2:

    As @Heinzi pointed out @jmcilhinney's answer isn't correct. Use mine! :)