繁体   English   中英

当UploadFromStream到Azure blob时,最大请求长度超出了异常

[英]Maximum request length exceeded exception when UploadFromStream to Azure blobs

我编写了一个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上的一些教程改变了我的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()

更改为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);
}  

我希望这可以帮助别人。

下面是一个示例,它将一个随机的20MB字节数组从控制台客户端上传到Web API控制器,该控制器将HTTP请求内容流式传输到Azure blob存储中:

样品

请注意,它在客户端缓冲(在内存中构建整个20MB字节数组),但它不在服务器上缓冲。

我在笔记本电脑上运行的客户端成功测试了这个,并且服务器在本地和Azure Web App中运行(没有额外的配置,只是将Web API项目发布到Azure Web应用程序中)。

希望这有助于......祝您好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM