views:

1757

answers:

4

Hey, I'm currently trying to send an image file to a web server using a web request, a memory stream and an image object.

This is my current method for sending the request:

    public void Send(Image image)
    {
        //Assign the request here too, just in case
        Request = (HttpWebRequest)WebRequest.Create(FormURL);

        Request.Method = "POST";
        Request.ContentType = "multipart/form-data; boundary=" + CONTENT_BOUNDARY;
        Request.Headers.Add("Cache-Control", "no-cache");
        Request.KeepAlive = true;
        Request.ContentLength = GetFormElements().Length +
        GetFileHeader(FileName).Length +
        FILE_TRAIL.Length +
        ConvertImageToByteArray(image).Length;

        //Must be done in this order for stream to write properly:
        //----
        //Form elements
        //File header
        //Image
        //File trailer
        //----
        WriteStringToStream(FileStream, GetFormElements());
        WriteStringToStream(FileStream, GetFileHeader(FileName));
        WriteImageToStream(FileStream, image);
        WriteStringToStream(FileStream, FILE_TRAIL);

        string PostData = ASCIIEncoding.ASCII.GetString(ConvertImageToByteArray(image));

        StreamWriter SW = new StreamWriter(Request.GetRequestStream(), Encoding.ASCII);
        SW.Write(PostData);

        GetRequestResponse();
        Console.WriteLine(Request.HaveResponse);
        FileStream.Close();
        Request = null;

    }

The problem I am having is that I'm not getting ANY response from the server at all, despite the stream being what looks to be a correct length (I removed some debug outputs from the code above)

If necessary, I can post other parts of my class, but for now here are the writing functions:

WriteStringToStream:

    private void WriteStringToStream(System.IO.MemoryStream stream, string String)
    {
        byte[] PostData = System.Text.Encoding.ASCII.GetBytes(String);
        stream.Write(PostData, 0, PostData.Length);
    }

WriteImageToSteam:

private void WriteImageToStream(System.IO.MemoryStream Stream, Image img)
{
    Stream.Write(ConvertImageToByteArray(img), 0, ConvertImageToByteArray(img).Length);
}

ConvertImageToByteArray:

    private Byte[] ConvertImageToByteArray(Image img)
    {
        //Method taken from http://www.csharp-station.com/Articles/Thumbnails.aspx and adapted
        MemoryStream memStream = new MemoryStream();
        img.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg);

        byte[] byteArray = new Byte[memStream.Length];

        memStream.Position = 0;
        memStream.Read(byteArray, 0, (int)memStream.Length);
        return byteArray;
    }
A: 

what's the purpose of "FileStream"? The declaration isn't shown, you write data to, then just close it. Did you mean to write it to the request stream and forgot? Seems like you count it in Request.ContentLength, but never write it to the request.

Ben Schwehn
I added in the writing to the request stream just before you replied, I accidentally removed it when posting it here
but after the line WriteStringToStream(FileStream, FILE_TRAIL);FileStream is only accessed once more - to close it. Perhaps I'm missing something.
Ben Schwehn
That's my fault, when I removed some debug outputs for displaying the code here, I accidentally took out the stream writer too - I've replaced it in the code here now (it was in the code on my machine all along)
+2  A: 

You should close SW before sending the request.

Also, instead of converting the byte array to ASCII and then writing it to a StreamWriter, you should write the byte array directly to the request stream. (And then close the request stream before sending the request)

SLaks
Ok, I've written the byte array directly in to the request stream. However, I now get an error when trying to close the request stream "The request was aborted: The request was canceled." - using Request.GetRequestStream().Close(); - as well as an error if I try to close the stream writer
A: 
        private void GetRequestResponse()
    {
        if (null == FileStream)
        {
            System.IO.Stream stream;
            WebResponse webResponse;
            try
            {
                webResponse = Request.GetResponse();
            }
            catch (WebException web)
            {
                webResponse = web.Response;
            }

            if (null != webResponse)
            {
                stream = webResponse.GetResponseStream();
                StreamReader sr = new StreamReader(stream);
                string str;
                Response = "";

                while ((str = sr.ReadLine()) != null)
                {
                    Response += str;
                }
                webResponse.Close();
            }
            else
            {
                throw new Exception("Error retrieving server response");
            }
        }
    }

In response to SLaks, the above is the contents of the GetRequestResponse. In this class, Response is just a string.

A: 

Problem solved :) I now have a response - even if it isn't what I was expecting ...