2013-06-03 13 views
6

Sto provando a caricare i file dal client della riga di comando locale nell'archiviazione di Azure tramite web-api. Sto utilizzando il sito Web di Azure per questo. Lavorare con il cliente non è un problema. E ho tutto a posto a livello locale bene. Ecco il codice web-API:Carica i file nello storage Azure Blob tramite WebApi senza accedere al filesystem locale

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); 
    } 

Tutto funziona bene quando ho eseguito a livello locale, ma non appena mi schiero sito web in Azure, non riesco a caricare, a causa Azure siti web non hanno accesso a LocalResource. E ho bisogno di passare al ruolo Web di Azure. Posso passare, ma l'accesso al file system locale mi dà fastidio tutti insieme.

E LocalResource è necessario, ad esempio, per MultipartFormDataStreamProvider(). E non ho trovato modi alternativi per caricare file su WebApi. Il mio piano era di channel through upload directly to Azure, senza memorizzare nulla su un HDD locale.

C'è un altro modo per caricare file?

p.s. Ho visto usages of Shared Access Signatures dove posso dare un URL dell'applicazione client con la firma e lasciare che il client carichi direttamente sul blog di Azure. Ma non sono sicuro di quanto sarà sicuro e non molto comodo (ancora) con il passaggio delle firme al cliente. Al momento presumo che il client verrà eseguito in un ambiente molto ostile e non ci si può fidare di nulla che ritorni dal client.

UPD La mia soluzione finale riguardava l'utilizzo della firma di accesso condiviso di sola scrittura rilasciata sul server e trasmessa al client. Il client quindi carica i file direttamente in Azure. In questo modo risparmi un sacco di problemi con la gestione dei file caricati. Ed ecco more detailed description della mia soluzione.

+0

Quale eccezione viene lanciata dal seguente codice "localResource = RoleEnvironment.GetLocalResource (" TempStorage ")" –

+0

è comodo utilizzare l'API REST? –

+0

@BrianDishaw L'eccezione è qualcosa sulla falsariga di "Impossibile acquisire LocalResource, System.Runtime.InteropServices.SEHException (0x80004005): il componente esterno ha generato un'eccezione. "Anche questa pagina (http://msdn.microsoft.com/en-us/library/windowsazure/ee758708.aspx) suggerisce che le risorse locali sono solo per Web e Ruolo di lavoro, non per i siti Web. – trailmax

risposta

11

Questa non è esattamente la risposta che si sta cercando, ma è possibile utilizzare la memoria locale con i siti Web di Azure utilizzando MultiPartFileStreamProvider e Path.GetTempPath(). Il codice dovrebbe essere simile a questo

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

Ora mi chiedo come Azure gestisca TempPath() nei siti Web e quanto sia affidabile. Potrebbe non essere cancellato a metà del caricamento di file di grandi dimensioni? – trailmax

+0

dead link, Daniel. – Bon

+0

Ho rimosso il collegamento morto che indicava che la directory temporanea non era transitoria. Per quanto ne so, è ancora vero. –

1

Una possibile soluzione per ottenere il codice per lavorare come è con un LocalResource potrebbe essere quella di ospitare questo all'interno di un processo di lavoro che l'auto-host web api via Owin.

Si può trovare una semplice procedura dettagliata a: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-role

Hai solo bisogno di avvio l'API Owin ospitato all'interno del metodo OnStart() della RoleEntryPoint. Tieni presente che puoi anche restituire Html da una risposta API Web in modo da rendere il ruolo di un lavoratore un progetto di base molto flessibile.

Ecco un breve frammento di che mostra come impostare l'host Owin dal link qui sopra:

+0

Potrei aver appena implementato il sito in un ruolo web e avere una risorsa locale disponibile. Distribuire solo web-api in un ruolo di lavoro è eccessivo. Ad ogni modo, ho risolto il problema emettendo la firma di accesso condiviso di sola scrittura nell'archiviazione BLOB, passandola al client tramite WebApi. E poi il client carica i file direttamente in Azure. – trailmax

Problemi correlati