Question

Yesterday I asked this question. Rubens Farias answered it by pointing to this piece of code he wrote. The following part of it cannot be compiled by MS Visual Studio 2010 Professional Beta 2.

byte[] buffer = 
Encoding.UTF8.GetBytes(
    String.Join("&", 
        Array.ConvertAll<KeyValuePair<string, string>, string>(
            inputs.ToArray(),
            delegate(KeyValuePair item)
            {
                return item.Key + "=" + HttpUtility.UrlEncode(item.Value);
            })));

It gives these errors in Visual Studio. Unfortunately Rubens doesn't reply anymore.

So I have the following questions / requests:

  1. I don't understand this piece of code, please explain what is happening exactly.
  2. Please explain how this part has te be rewritten in order for it to "work" in VS.
  3. Please explain how I should convert it to VB.NET. I have tried it using online converters to no avail.
Was it helpful?

Solution

  • KeyValuePair requires two type arguments. In your delegate declaration it says simply KeyValuePair item, with no type arguments. Change this to delegate(KeyValuePair<string,string> item)
  • HttpUtility is declared in the System.Web namespace; add using System.Web; to the using statements in the beginning of the file.

Personally I find it easier and cleaner to use lambda style for this kind of code:

byte[] buffer =
     Encoding.UTF8.GetBytes(
         String.Join("&",
             Array.ConvertAll<KeyValuePair<string, string>, string>(
                 inputs.ToArray(), (item) => item.Key + "=" + HttpUtility.UrlEncode(item.Value))));

Once you have gotten the C# code to work, the DeveloperFusion C# to VB.NET converter does the job:

' Converted from delegate style C# implementation '
Dim buffer As Byte() = Encoding.UTF8.GetBytes( _
    [String].Join("&", _
    Array.ConvertAll(Of KeyValuePair(Of String, String), String)(inputs.ToArray(), _
        Function(item As KeyValuePair(Of String, String)) (item.Key & "=") + HttpUtility.UrlEncode(item.Value))))

' Converted from Lambda style C# implementation '
Dim buffer As Byte() = Encoding.UTF8.GetBytes( _
    [String].Join("&", _
    Array.ConvertAll(Of KeyValuePair(Of String, String), String)(inputs.ToArray(), _
        Function(item) (item.Key & "=") + HttpUtility.UrlEncode(item.Value))))

OTHER TIPS

byte[] buffer = 
Encoding.UTF8.GetBytes(
    String.Join("&", 
        Array.ConvertAll<KeyValuePair<string, string>, string>(
            inputs.ToArray(),
            delegate(KeyValuePair<string, string> item)
            {
                return item.Key + "=" + System.Web.HttpUtility.UrlEncode(item.Value);
            })));

Try that.

  1. The code appears to be building a GET request list of items e.g. key1=value1&key2=value2. This is done by first converting the inputs array into individual elements of key=value then String.Joining them together with an ampersand. It then returns the UTF8 bytes in an array.

  2. This works (see code).

  3. I'm not a VB.NET programmer, sorry, but I'll have a go in a second.

It is converting the inputs list containing Key/Value pairs into a string that looks much like a query string (eg. item1=value1&item2=value2), then converting that into the buffer byte array using UTF8 encoding.

Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim inputs As New List(Of KeyValuePair(Of String, String))
        inputs.Add(New KeyValuePair(Of String, String)("a", "adata"))

        Dim buffer As Byte() = _
            Encoding.UTF8.GetBytes( _
                String.Join("&", _
                Array.ConvertAll(Of KeyValuePair(Of String, String), String)( _
                    inputs.ToArray(), _
                    Function(item As KeyValuePair(Of String, String)) _
                    item.Key & "=" & HttpUtility.UrlEncode(item.Value) _
                )))
    End Sub
End Class
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow