簡體   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