使用ASP.Net Webapi实现大图片的流式传输

17
我们正在尝试使用ASP.Net WebApi返回大型图像文件,并使用以下代码将字节流传输到客户端。
public class RetrieveAssetController : ApiController
{
    // GET api/retrieveasset/5
    public HttpResponseMessage GetAsset(int id)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
        string filePath = "SomeImageFile.jpg";

        MemoryStream memoryStream = new MemoryStream();

        FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read);

        byte[] bytes = new byte[file.Length];
        file.Read(bytes, 0, (int)file.Length);

        memoryStream.Write(bytes, 0, (int)file.Length);

        file.Close();

        httpResponseMessage.Content =  new ByteArrayContent(memoryStream.ToArray());
        httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        httpResponseMessage.StatusCode = HttpStatusCode.OK;

        return httpResponseMessage;
    }
}

以上代码运行良好,但我们处理的一些文件可能会超过2GB大小,从而导致连接超时。我们过去曾经使用类似以下的代码(使用HttpHandlers)将响应分块到响应流中以保持连接成功。

byte[] b = new byte[this.BufferChunkSize];
int byteCountRead = 0;

while ((byteCountRead = stream.Read(b, 0, b.Length)) > 0)
{
    if (!response.IsClientConnected) break;

    response.OutputStream.Write(b, 0, byteCountRead);
    response.Flush();
}

我们如何使用早期展示的新WebAPI编程模型来使用类似的技术?

2个回答

26

@FIllip W - 首先,非常感谢您的帮助。我没有使用4.5框架的奢侈条件,因此无法使用4.5框架的内置异步功能。这种方法可以使用4.0框架库吗?更具体地说,“WriteToStream”操作会如何改变?我是否可以只读取每个字节块并将其写入输出流而不必担心异步部分? - raj
是的,Web API 中的所有内容都与 4.0 兼容。您可以只需删除 async/await 并使整个过程同步,或者在代码等待的任何地方使用 continuations(ContinueWith)。 - Filip W
@FIllip W - 这对我来说非常有效。再次感谢您的帮助。我已经接受了您的答案。再次感谢。 - raj

0

我在这个实现中遇到了严重的问题(比如下载未完成)。某些东西让客户端认为它没有所有的内容! - Norman H
@NormanH 奇怪,我认为某些东西正在“中断”下载,可能是客户端因为服务器上的某些操作“太长时间”而放弃,或者你意外地搞乱了原始文件流?我以前做过这样的事情,将一个流放入某个对象中,然后过早地处理读取器/写入器(根据设置关闭正在处理的流)。也许你限制了文件读取,或者源文件在流传输过程中被移动/删除了? - drzaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接