2015-06-23 9 views
5

Vorrei esporre un'azione ASP.Net Web Api 2 utilizzando il verbo HTTP PUT per caricare i file. Questo è coerente con il nostro modello REST in quanto l'API rappresenta un file system remoto (simile a WebDAV, ma davvero semplificato), quindi il client sceglie i nomi delle risorse (quindi PUT è l'ideale e POST non è una scelta logica).Carica il file utilizzando il verbo PUT in ASP.Net Web Api 2

La documentazione Web Api descrive how to upload files using multipart/form-data forms, ma non descrive come farlo utilizzando i metodi PUT.

Che cosa utilizzeresti per testare tale API (i moduli HTML multipart non consentono i verbi PUT)? Sarebbe l'implementazione del server apparire come l'attuazione multipart descritto the web api documentation (utilizzando il MultipartStreamProvider), o dovrebbe assomigliare a questo:

[HttpPut] 
public async Task<HttpResponseMessage> PutFile(string resourcePath) 
{ 
    Stream fileContent = await this.Request.Content.ReadAsStreamAsync(); 
    bool isNew = await this._storageManager.UploadFile(resourcePath, fileContent); 
    if (isNew) 
    { 
     return this.Request.CreateResponse(HttpStatusCode.Created); 
    } 
    else 
    { 
     return this.Request.CreateResponse(HttpStatusCode.OK); 
    } 
} 

risposta

8

Dopo alcuni test sembra che il codice lato server che ho postato come esempio è corretto . Ecco un esempio, spogliato di qualsiasi codice di gestione autenticazione/autorizzazione/errore:

[HttpPut] 
[Route(@"api/storage/{*resourcePath?}")] 
public async Task<HttpResponseMessage> PutFile(string resourcePath = "") 
{ 
    // Extract data from request 
    Stream fileContent = await this.Request.Content.ReadAsStreamAsync(); 
    MediaTypeHeaderValue contentTypeHeader = this.Request.Content.Headers.ContentType; 
    string contentType = 
     contentTypeHeader != null ? contentTypeHeader.MediaType : "application/octet-stream"; 

    // Save the file to the underlying storage 
    bool isNew = await this._dal.SaveFile(resourcePath, contentType, fileContent); 

    // Return appropriate HTTP status code 
    if (isNew) 
    { 
     return this.Request.CreateResponse(HttpStatusCode.Created); 
    } 
    else 
    { 
     return this.Request.CreateResponse(HttpStatusCode.OK); 
    } 
} 

Una console semplice applicazione è sufficiente per testarlo (utilizzando librerie client Web Api):

using (var fileContent = new FileStream(@"C:\temp\testfile.txt", FileMode.Open)) 
using (var client = new HttpClient()) 
{ 
    var content = new StreamContent(fileContent); 
    content.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); 
    client.BaseAddress = new Uri("http://localhost:81"); 
    HttpResponseMessage response = 
     await client.PutAsync(@"/api/storage/testfile.txt", content); 
} 
+1

Sarebbe interessante vedere come scrivere un corretto test di unità per questo, piuttosto che affidarsi all'esecuzione di un server HTTP. – James

+0

Ho avuto un sacco di problemi nel far funzionare tutto questo mentre continuavo a ricevere 404 errori. Risulta che potrebbe essere necessario cambiare il web.config per accettare i nomi dei file del modulo '{nomefile}. {Estensione}'. Vedi questa domanda StackOverflow per i dettagli: http://stackoverflow.com/questions/20998816/dot-character-in-mvc-web-api-2-for-request-such-as-api-people-staff-45287 –

Problemi correlati