我正试图找出一种通过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)
答案 0 :(得分:1)
正如您提供的链接中所述,您需要在服务中将缓冲区策略设置为非缓冲模式,因为默认情况下策略是缓冲区。
StreamContent可以保存缓冲区或非缓冲流,但它不会决定主机上的请求流是否应该缓冲。它的主机层做出了这个决定。