C# read image object in to web request

2019-06-13 19:53发布

问题:

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;
    }

回答1:

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)



回答2:

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.



回答3:

        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.



回答4:

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