我编写了一个API,试图通过c#中的Stream将HTTP帖子内容(我正在尝试上传视频)上传到Azure blob。 有点像这样:
Stream videoStream = await Request.Content.ReadAsStreamAsync();
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
blockBlob.UploadFromStream(videoStream);
它在我的本地环境中正常工作。但是,当我将此Web服务部署到Azure并调用API时,我得到了“超出最大请求长度”异常,如下所示:
System.Web.HttpException (0x80004005): Maximum request length exceeded.
at System.Web.HttpBufferlessInputStream.ValidateRequestEntityLength()
at System.Web.HttpBufferlessInputStream.GetPreloadedContent(Byte[] buffer, Int32& offset, Int32& count)
at System.Web.HttpBufferlessInputStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Microsoft.Owin.Host.SystemWeb.CallStreams.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Web.Http.NonOwnedStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Http.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Microsoft.WindowsAzure.Storage.Core.Util.StreamExtensions.WriteToSync[T](Stream stream, Stream toStream, Nullable`1 copyLength, Nullable`1 maxLength, Boolean calculateMd5, Boolean syncRead, ExecutionState`1 executionState, StreamDescriptor streamCopyState)
at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(Stream source, Nullable`1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
我已经根据网络上的一些教程改变了我的Web.config,
<system.web>
<httpRuntime targetFramework="4.5" maxRequestLength="600000" executionTimeout="3600" />
<compilation debug="true" targetFramework="4.5" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="600000000" />
</requestFiltering>
</security>
</system.webServer>
API可以在我的本地计算机上正常运行,即使是一些大型视频(大于10MB)也是如此。 但是,只要我在Azure Web Service中部署,它就无法正常工作。 那是为什么?
更新:我使用了其他一些方法,试图绕过这个问题。 比如我尝试将HTTP请求内容复制到FileStream,并将FileStream上传到Azure blob。像这样的代码:
using (Stream output = File.OpenWrite(TmpFile))
{
await Request.Content.CopyToAsync(output);
}
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);
using (var fileStream = System.IO.File.OpenRead(TmpFile))
{
blockBlob.UploadFromStream(fileStream);
}
但同样的异常“超出最大请求长度”抛出函数CopyToAsync。
System.Web.HttpException (0x80004005): Maximum request length exceeded.
at System.Web.HttpBufferlessInputStream.ValidateRequestEntityLength()
at System.Web.HttpBufferlessInputStream.GetPreloadedContent(Byte[] buffer, Int32& offset, Int32& count)
at System.Web.HttpBufferlessInputStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at Microsoft.Owin.Host.SystemWeb.CallStreams.DelegatingStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Web.Http.NonOwnedStream.BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state)
at System.Net.Http.StreamToStreamCopy.StartRead()
答案 0 :(得分:7)
更改为Web.Config文件。
上述解决方案工作我认为我只需要添加必要的代码更改,而不是需要下载解决方案并搜索它以查找必要的更改。在system.web选项卡之间添加以下内容,这些选项卡应该已经存在,并且它们之间存在其他信息。
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" maxRequestLength="600000" executionTimeout="3600" />
</system.web>
然后在system.webserver选项卡之间添加以下内容,这些选项卡应该已经存在,并且它们之间存在其他信息。
<system.webserver>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="600000000" />
</requestFiltering>
</security>
之后,我将一个12.5 MB的.zip文件作为blob发送到azure文件存储。使用Azure提供的代码。
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
// Retrieve reference to a blob named "myblob".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("myblob");
// Create or overwrite the "myblob" blob with contents from a local file.
using (var fileStream = System.IO.File.OpenRead(@"path\myfile"))
{
blockBlob.UploadFromStream(fileStream);
}
我希望这有助于某人。
答案 1 :(得分:1)
这是一个示例,它将一个随机的20MB字节数组从控制台客户端上传到Web API控制器,后者将HTTP请求内容流式传输到Azure blob存储中:
请注意,它在客户端缓冲(在内存中构建整个20MB字节数组),但它不在服务器上缓冲。
我使用在笔记本电脑上运行的客户端成功测试了这个,并且服务器在本地和Azure Web App中运行(没有额外的配置,只是将Web API项目发布到Azure Web应用程序中)。
希望这有助于......祝你好运!