通过web api将文件上传到Azure blob

时间:2014-01-24 07:10:03

标签: azure file-upload asp.net-web-api

我正试图找出一种通过web api上传文件的方法,而不必将整个文件保存到磁盘或内存中。

这是我的api控制器代码:

public async Task<IHttpActionResult>Post([FromUri] string ext) 
{
  string fileName = string.Concat(Guid.NewGuid(), ext);
  var blob = AzureBlobContainer.GetBlockBlobReference(fileName);
  await blob.UploadFromStream(await Request.Content.ReadAsStreamAsync()); // here is the issue
  return Ok();
}

我正在使用HttpClient进行上传:

public async Task<bool> Upload(string requestUrl, Stream fileStream)
{
  var progress = new ProgressMessageHandler();
  progress.HttpSendProgress += HttpSendProgress;
  var client = HttpClientFactory.Create(progress);
  HttpResponseMessage response = await client.PostAsync(requestUrl, new StreamContent(fileStream));
  response.EnsureSuccessStatusCode();
  return response.IsSuccessStatusCode;
}

private void HttpSendProgress(object sender, HttpProgressEventArgs e)
{
  Debug.WriteLine("progress is {0}% ({1} of {2})", e.ProgressPercentage, e.BytesTransferred, e.TotalBytes);
}

此代码将成功将文件上载到Azure。但是,整个文件将在Web api服务器上进行缓冲,然后复制到Azure。这会导致来自progress事件的消息在文件上载到api控制器时计数达到100%,然后在文件上载到Azure时显示阻止。 我理解,因为我使用的是StreamContent,所以web api不应该缓冲我的上传。

在这个问题中讨论了一个解决方案,这使我认为这是可能的:WebAPI Request Streaming support

我的客户端代码位于可移植的类库中,因此无法依赖Azure .net存储库(因此我不能直接上传到Azure,除非我使用底层的REST API)

1 个答案:

答案 0 :(得分:1)

正如您提供的链接中所述,您需要在服务中将缓冲区策略设置为非缓冲模式,因为默认情况下策略是缓冲区。

StreamContent可以保存缓冲区或非缓冲流,但它不会决定主机上的请求流是否应该缓冲。它的主机层做出了这个决定。