views:

415

answers:

2

I'm trying to send some data using a simple HTTP POST in Silverlight 3.0 but for some reason I can't seem to find a good example on how to do this.

So far this works, but how do I send some data along w/ the request?

Public Sub SubmitMessage()
    request = WebRequestCreator.ClientHttp.Create(New System.Uri("http://localhost:27856/Home.aspx/PostUpdate/"))
    request.Method = "POST"

    Dim result As IAsyncResult = request.BeginGetResponse(New AsyncCallback(AddressOf UpdateDone), Nothing)
End Sub

Public Sub UpdateDone(ByVal ar As IAsyncResult)
    Dim response As HttpWebResponse = request.EndGetResponse(ar)

    Using reader As StreamReader = New StreamReader(response.GetResponseStream())
        Dim valid As String = reader.ReadToEnd()
    End Using
End Sub
+1  A: 

You need the BeginGetRequestStream method before getting the response (note VB.NET is not my main language).

Public Sub SubmitMessage()
    request = WebRequestCreator.ClientHttp.Create(New System.Uri("http://localhost:27856/Home.aspx/PostUpdate/"))
    request.Method = "POST"

    request.BeginGetRequestStream(New AsyncCallback(AddressOf SendData), Nothing)
End Sub

Public Sub SendData(ByVal ar As IAsyncResult)
    Dim stream as Stream = state.Request.EndGetRequestStream(ar)
    '' # Pump your data as bytes into the stream.
    stream.Close()
    request.BeingGetResponse(New AsyncCallback(AddressOf UpdateDone), Nothing)
End Sub

Public Sub UpdateDone(ByVal ar As IAsyncResult)
    Dim response As HttpWebResponse = request.EndGetResponse(ar)

    Using reader As StreamReader = New StreamReader(response.GetResponseStream())
        Dim valid As String = reader.ReadToEnd()
    End Using
End Sub

It would seem from your answer that the are posting HTML form data. Here is the correct way to create the entity body (C# sorry):-

 public static string GetUrlEncodedData(Dictionary<string, string> data)
 {
  var sb = new StringBuilder();
  foreach (var kvp in data)
  {
   if (sb.Length > 0) sb.Append("&");
   sb.Append(kvp.Key);
   sb.Append("=");
   sb.Append(Uri.EscapeDataString(kvp.Value));
  }
  return sb.ToString();
 }

Note in particular the use of Uri.EscapeDataString, this the correct way to encode data values for this Content-Type. It assumes that the server is expecting UTF-8 character encoding.

When converting the result of this to a byte array ready for posting you need only use ASCII encoding since the returned string will only ever contain characters within the ASCII range.

AnthonyWJones
Directly after the request.BeginGetResponse(... the http POST is done and it jumps to the url mentioned w/out the stream attached. Any way to attach this stream before this call in the first method above?
Toran Billups
Looks like a small typo in your answer but it got me moving in the right direction! I posted the final solution to clear up any confusion around this! Thanks for the reply!
Toran Billups
Oops, yes I quote the correct method but failed to actually tweak the code with it, done now.
AnthonyWJones
+1  A: 

The final solution that worked is shown below. Thanks to @AnthonyWJones for his quick answer that got me moving in the right direction!

Public Sub SubmitMessage()
    Dim request As HttpWebRequest = WebRequestCreator.ClientHttp.Create(New System.Uri("http://localhost:27856/Home.aspx/PostUpdate/"))
    request.Method = "POST"
    request.ContentType = "application/x-www-form-urlencoded"

    request.BeginGetRequestStream(New AsyncCallback(AddressOf SendStatusUpdate), request)
End Sub

Public Sub SendStatusUpdate(ByVal ar As IAsyncResult)
    Dim request As HttpWebRequest = DirectCast(ar.AsyncState, HttpWebRequest)

    Dim stream As Stream = request.EndGetRequestStream(ar)

    Dim data As New System.Text.UTF8Encoding
    Dim byteArray As Byte() = data.GetBytes("status=test")

    stream.Write(byteArray, 0, byteArray.Length)
    stream.Close()
    stream.Dispose()

    request.BeginGetResponse(New AsyncCallback(AddressOf StatusUpdateCompleted), request)
End Sub

Public Sub StatusUpdateCompleted(ByVal ar As IAsyncResult)
    Dim request As HttpWebRequest = DirectCast(ar.AsyncState, HttpWebRequest)

    Dim response As HttpWebResponse = request.EndGetResponse(ar)

    Using reader As StreamReader = New StreamReader(response.GetResponseStream())
        Dim valid As String = reader.ReadToEnd()
    End Using
End Sub
Toran Billups
The default encoding for UploadStringAsync is UTF-8, have you tried using that? Besides for true HTML form emulation this form of encoding is incorrect. Is there are reason your not posting something like a XML or JSON?
AnthonyWJones