如何正确地通过休息服务传递流以检索其长度

时间:2013-04-11 04:25:41

标签: c# stream wcf-web-api

我正在以这种方式传递信息流:

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

然后在服务器上处理它:

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;

    ...
}  

现在我在致电NotSupportedException时收到fileData.Length。我知道它发生是因为流已关闭。但是我该如何重新打开呢?或者我应该怎么做,当我将流传递给服务时,我仍然可以得到它的长度?

1 个答案:

答案 0 :(得分:1)

为什么不传递内容长度标题?您的服务器可以检查标头并确切知道正在发送的内容的字节数。如何阅读标题取决于您使用的是哪个http框架,ASP.NET Web Api,经典WCF Web Api,HttpListener等。

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

如果没有Content-Length标头,http服务器永远不会知道要读取多少字节。所有它知道是有一个流,并将读取它,直到没有更多的数据。这也是您的浏览器在下载内容时显示进度条的方式。需要bytesDownloaded / Content-Length。

根据这篇文章:https://stackoverflow.com/a/8239268/1160036

您可以通过网络方式访问此标题。

long dataLength = long.Parse(HttpContext.Current.Request.Headers["Content-Length"]);