2013-06-03 79 views
6

我試圖通過web-api將文件從本地命令行客戶端上傳到Azure存儲。 我正在使用Azure Web站點。與客戶合作不成問題。我已經在本地工作得很好。這裏是網上API代碼:通過WebApi將文件上傳到Azure Blob存儲而不訪問本地文件系統

public async Task<HttpResponseMessage> PostUpload() 
    { 
     // need a local resource to store uploaded files temporarily 
     LocalResource localResource = null; 
     try 
     { 
      // Azure web-site fails here 
      localResource = RoleEnvironment.GetLocalResource("TempStorage"); 
     } 
     catch (Exception e) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to get access to local resources"); 
     } 

     var provider = new MultipartFormDataStreamProvider(localResource.RootPath); 

     // Read the form data. 
     await Request.Content.ReadAsMultipartAsync(provider); 

     // snipped validation code 
     var container = // code to get container 

     foreach (var fileData in provider.FileData) 
     { 
      var filename = GetBlobName(fileData); 
      var blob = container.GetBlockBlobReference(filename); 
      using (var filestream = File.OpenRead(fileData.LocalFileName)) 
      { 
       blob.UploadFromStream(filestream); 
      } 
      File.Delete(fileData.LocalFileName); 
     } 

     return Request.CreateResponse(HttpStatusCode.OK); 
    } 

一切工作正常,當我在本地運行,但只要我在Azure中部署的網站,我不能上傳,因爲Azure的web站點不具備訪問LocalResource。我需要切換到Azure Web角色。我可以切換,但訪問本地文件系統一起困擾着我。

MultipartFormDataStreamProvider()的實例需要LocalResource。我還沒有找到其他方法將文件上傳到WebApi。我的計劃是channel through upload directly to Azure,沒有在本地硬盤上存儲任何東西。

有沒有其他的方式來上傳文件?

p.s.我已經看到了usages of Shared Access Signatures,我可以在其中向客戶端應用程序提供具有籤​​名的url,並讓客戶端直接上傳到Azure博客。但是我不確定這樣的安全性如何,並且在將簽名傳遞給客戶端時還不太舒服。目前我認爲客戶將會在非常惡劣的環境中運行,並且客戶不會相信任何東西。

UPD我的最終解決方案涉及使用只寫共享訪問簽名服務器上發出並傳遞到客戶端。然後客戶端將文件直接上傳到Azure。通過這種方式,我可以節省很多管理上傳文件的麻煩。這裏是我的解決方案的more detailed description

+0

下面的代碼拋出了什麼異常「localResource = RoleEnvironment.GetLocalResource(」TempStorage「)」 –

+0

你很喜歡使用REST API嗎? –

+0

@BrianDishaw異常是沿着「無法獲取LocalResource,System.Runtime.InteropServices。SEHException(0x80004005):外部組件引發異常。「此頁面(http://msdn.microsoft.com/en-us/library/windowsazure/ee758708.aspx)建議本地資源僅用於Web-和工作者角色,而不是網站 – trailmax

回答

11

這不是您正在尋找的答案,但您可以使用本地存儲與Azure網站使用MultiPartFileStreamProvider和Path.GetTempPath()。該代碼會是這個樣子

public async Task<HttpResponseMessage> PostUpload() 
{ 
    var provider = new MultipartFileStreamProvider(Path.GetTempPath()); 

    // Read the form data. 
    await Request.Content.ReadAsMultipartAsync(provider); 

    // do the rest the same  
} 
+0

現在我想知道Azure如何管理網站中的TempPath()以及它的可靠性如何。難道不能通過大文件上傳中途擦掉?丹尼爾,死鏈接 – trailmax

+0

。 – Bon

+0

我已經刪除了表示臨時目錄不是臨時的死鏈接。據我所知,這仍然是事實。 –

1

一個可能的解決方案,使你的代碼工作,因爲是用LocalResource將通過Owin舉辦這樣的工作進程,自我主機的網絡API的內部。

你可以找到一個簡單的演練:http://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-role

你只需要在RoleEntryPoint的的OnStart()方法中啓動的Owin託管API。請記住,您也可以從web api響應中返回Html,這樣您就可以使工作者角色成爲一個非常靈活的基礎項目。

這裏展示瞭如何建立從上面的鏈接Owin主機快速片段:

+0

我可以將網站部署到網絡角色並擁有LocalResource。將web-api部署到工作者角色是一種矯枉過正的行爲。無論如何,我通過在BLOB存儲中發佈只寫共享訪問簽名來解決此問題,並通過WebApi將其傳遞給客戶端。然後客戶端直接將文件上傳到Azure。 – trailmax

相關問題