2017-02-17 99 views
1

我想实现简单的视频文件流。 还有就是我的API控制器:如何在ASP.Net MVC中实现视频文件流?

[HttpGet] 
[Route("api/VideoContent")] 
public HttpResponseMessage GetVideoContent([FromUri] string fileName) 
{ 
    if (fileName == null) 
    { 
     return new HttpResponseMessage(HttpStatusCode.BadRequest); 
    } 

    if (Request.Headers.Range != null) 
    { 
     try 
     { 
      //using (FileStream fileStream = _videoFileProvider.GetFileStream(fileName)) 
      //{ 
       HttpResponseMessage partialResponse = Request.CreateResponse(HttpStatusCode.PartialContent); 
       FileStream fileStream = _videoFileProvider.GetFileStream(fileName); 
       partialResponse.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, new MediaTypeHeaderValue("video/mp4")); 
       return partialResponse; 
      //} 

     } 
     catch (Exception) 
     { 
      return new HttpResponseMessage(HttpStatusCode.InternalServerError); 
     } 
    } 

    return new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable); 
} 

此代码的工作,但你看到FILESTREAM没有配置。我试图使用块(注释行),但这段代码不起作用 - 在调试模式下运行时没有例外,但浏览器显示500错误代码的响应。

我的错误在哪里?为什么我得到500内部服务器错误?如何在我的情况下正确处理文件流?

+0

[Maxad有一个很好的答案](http://stackoverflow.com/questions/16862782/streaming-large-video-files-net)通过finally块关闭流。 – Ethilium

回答

2

AFAIK,你没有处理文件流下载内容的实现是正确的。

由于您已经使用HttpResponseMessage来返回响应,该响应在向客户端发送响应完成后由框架自动处理。

这一点已经在another post

如果你着眼于HttpResponseMessage in source code Dispose方法comment指出通过MSFT guy

 protected virtual void Dispose(bool disposing) 
     { 
      // The reason for this type to implement IDisposable is 
      //that it contains instances of types that implement 
      // IDisposable (content). 
      if (disposing && !_disposed) 
      { 
       _disposed = true; 
       if (_content != null) 
       { 
        _content.Dispose(); 
       } 
      } 
     } 

你可以看到_ content已经布置是HttpContent的类型,例如在您的情况,ByteRangeStreamContent的对象设置在 HttpResponseMessage的属性中。

处置的实现方式是ByteRangeStreamContent对象:

 protected override void Dispose(bool disposing) 
     { 
      Contract.Assert(_byteRangeContent != null); 
      if (disposing) 
      { 
       if (!_disposed) 
       { 
        _byteRangeContent.Dispose(); 
        _content.Dispose(); 
        _disposed = true; 
       } 
      } 
      base.Dispose(disposing); 
     } 

ByteRangeStreamContent上述Dispose方法,你可以看到它正在部署本身和处理_ content(在你的情况FileStream),以及它是用于流用于创建ByteRangeStreamContent对象。

我坚信,无需配置文件流,您的实现就是正确的,因为在发送响应到客户端时,按顺序开始处理。