Question

I'm passing the stream this way:

StreamReader sr = new StreamReader(openFileDialog1.FileName);
byte[] fileStream = Utility.ReadFully(sr.BaseStream);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
request.Method = "POST";
request.ContentType = "application/octet-stream";

Stream serverStream = request.GetRequestStream();
serverStream.Write(fileStream, 0, fileStream.Length);
serverStream.Close();

HttpWebResponse response2 = (HttpWebResponse)request.GetResponse();
if (response2.StatusCode == HttpStatusCode.OK)
{
    MessageBox.Show(Utility.ReadResponse(response2));
}  

-------------------------------------------------------------------------

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16 * 1024];
    using (MemoryStream ms = new MemoryStream())
    {
        if (input != null)
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
        }
        return ms.ToArray();
    }
}  

Then handling it on the server:

public bool UploadPhotoStream(string someStringParam, Stream fileData)
{
    string filePath = string.Format("{0}/{1}", 'sdfgsdf87s7df8sd', '24asd54s4454d5f4g');

    ProductPhoto newphoto = new ProductPhoto();
    newphoto.FileSizeBytes = fileData.Length / 1024 / 1024;
    newphoto.FileLocation = filePath;

    ...
}  

Now I'm getting NotSupportedException when calling fileData.Length. I know it happens because the stream is closed. But how can I re-open it? Or what should I do so that when I pass the stream to the service I can still get its length?

Was it helpful?

Solution

Why don't you pass content-length header? Your server can check the header and know exactly how many bytes is the content being sent. How you read the header depends on which http framework you are using, ASP.NET Web Api, classic WCF Web Api, HttpListener, etc.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.ContentLength = new FileInfo(openFileDialog1.FileName).Length

Without a Content-Length header, an http server can never know how many bytes are left to read. All it knows is there is a Stream and will read it till there is no more data. This is also how your browser can display a progress bar when downloading something. It takes bytesDownloaded / Content-Length.

According to this post: https://stackoverflow.com/a/8239268/1160036

You can access the header like this from your web method.

long dataLength = long.Parse(HttpContext.Current.Request.Headers["Content-Length"]);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top