views:

42

answers:

1

I have been trying to perform an HTTP Post request to upload an image in a silverlight application for a windows phone 7 application. The sample codes online do not get me the desired response from the API. Could anyone please provide a working code which does this?

By desired response I mean that the API responds saying that the uploaded file is in a format which cannot be read.

Thanks in advance!

Here is my code:

 private void post_image(version, username,password,job-id, serviceUri)
    {
        if (session_free.bLoggedIn)
        {                
            bool submit_success = false;

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(serviceUri));

            IsolatedStorageFileStream stream = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("file.jpg", FileMode.Open);

            request.PostMultiPartAsync(new Dictionary<string, object> { { "version", version }, { "username", user }, { "password", pass }, { filename, stream } }, new AsyncCallback(asyncResult =>
            {

                Thread.Sleep(1000);

                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);

                Stream responseStream = response.GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                Post_Result = reader.ReadToEnd();

                this.Dispatcher.BeginInvoke(delegate
                {
                   MessageBox.Show(Post_Result);
                    response.Close();
                });
            }), filename);

            Thread.Sleep(1000);
        }

        else
        {
            MessageBox.Show("User not signed in! Please login to continue...", "Invalid Authentication", MessageBoxButton.OK);
        }
    }

    public class DataContractMultiPartSerializer
{
    private string boundary;

    public DataContractMultiPartSerializer(string boundary)
    {
        this.boundary = boundary;
    }

    private void WriteEntry(StreamWriter writer, string key, object value, string filename)
    {

        if (value != null)
        {
            writer.Write("--");
            writer.WriteLine(boundary);
            if (value is IsolatedStorageFileStream)
            {
                IsolatedStorageFileStream f = value as IsolatedStorageFileStream;
                writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", key, filename);
                writer.WriteLine("Content-Type: image/jpeg");
                writer.WriteLine("Content-Length: " + f.Length);
                writer.WriteLine();
                writer.Flush();
                Stream output = writer.BaseStream;
                Stream input = f;
                byte[] buffer = new byte[4096];
                for (int size = input.Read(buffer, 0, buffer.Length); size > 0; size = input.Read(buffer, 0, buffer.Length))
                {
                    output.Write(buffer, 0, size);
                }
                output.Flush();
                writer.WriteLine();
            }

            else
            {
                writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""", key);
                writer.WriteLine();
                writer.WriteLine(value.ToString());
            }
        }
    }

    public void WriteObject(Stream stream, object data, string filename)
    {
        StreamWriter writer = new StreamWriter(stream);
        if (data != null)
        {


            if (data is Dictionary<string, object>)
            {
                foreach (var entry in data as Dictionary<string, object>)
                {
                    WriteEntry(writer, entry.Key, entry.Value, filename);
                }
            }

            else
            {
                foreach (var prop in data.GetType().GetFields())
                {
                    foreach (var attribute in prop.GetCustomAttributes(true))
                    {
                        if (attribute is System.Runtime.Serialization.DataMemberAttribute)
                        {
                            DataMemberAttribute member = attribute as DataMemberAttribute;
                            writer.Write("{0}={1}&", member.Name ?? prop.Name, prop.GetValue(data));
                        }
                    }
                }
            }
            writer.Flush();
        }
    }
}
+1  A: 

Is there a reason you're using a multipart message?
What is the PostMultiPartAsync method you're using? Presumably it's an extension method from somewhere?
In future, try and provide the smallest, complete, piece of code which demonstrates the issue.

Anyway, sorry it's not a full working example, but here are the steps for one way to do this.

Create request and set a calback for BeginGetRequestStream

var request = (HttpWebRequest)WebRequest.Create(App.Config.ServerUris.Login);

request.Method = "POST";
request.BeginGetRequestStream(ReadCallback, request);

In that callback, get the request stream and write your data to it.

using (var postStream = request.EndGetRequestStream(asynchronousResult))
{
    // Serialize image to byte array, or similar (that's what imageBuffer is)
    postStream.Write(imageBuffer, 0, imageBuffer.Length);
}

Set a callback for the response from the server.

request.BeginGetResponse(ResponseCallback, request);

Check that everything worked OK on the server

private void ResponseCallback(IAsyncResult asynchronousResult)
{
    var request = (HttpWebRequest)asynchronousResult.AsyncState;

    using (var resp = (HttpWebResponse)request.EndGetResponse(asynchronousResult))
    {
        using (var streamResponse = resp.GetResponseStream())
        {
            using (var streamRead = new StreamReader(streamResponse))
            {
                string responseString = streamRead.ReadToEnd();  // Assuming that the server will send a text based indication of upload success

                // act on the response as appropriate
            }
        }
    }
}

On the server you will need to deserialize the data and turn it back into an image as appropriate.

HTH.

Matt Lacey