2015-06-23 13 views
5

Chciałbym odsłonić działanie ASP.Net Web Api 2 przy użyciu czasownika HTTP PUT do przesyłania plików. Jest to spójne z naszym modelem REST, ponieważ API reprezentuje zdalny system plików (podobny do WebDAV, ale naprawdę uproszczony), więc klient wybiera nazwy zasobów (w ten sposób PUT jest idealny, a POST nie jest logicznym wyborem).Prześlij plik przy użyciu czasownika PUT w ASP.Net Web Api 2

Dokumentacja Api WWW opisuje how to upload files using multipart/form-data forms, ale nie opisuje, jak to zrobić za pomocą metod PUT.

Co byś użył do przetestowania takiego API (wieloczęściowe formularze HTML nie zezwalają na czasowniki PUT)? Czy wdrożenie serwera wyglądać wieloczęściowy realizacji opisanej w the web api documentation (używając MultipartStreamProvider), czy też powinna wyglądać następująco:

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

Odpowiedz

8

Po kilku badań wydaje się, że kod po stronie serwera, napisałem jako przykład jest poprawny . Oto przykład, pozbawiony z dowolnego kodu obsługi uwierzytelniania/autoryzacji/error:

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

Prosta aplikacja konsoli wystarczy go przetestować (przy użyciu bibliotek klienta 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

Byłoby ciekawe, jak napisać odpowiedni test jednostkowy, zamiast polegać na uruchomieniu serwera HTTP. – James

+0

Miałem wiele kłopotów z uzyskaniem tego, ponieważ ciągle otrzymywałem błędy 404. Okazuje się, że konieczna może być zmiana pliku web.config w celu zaakceptowania nazw plików w postaci '{filename}. {Extension}'. Zobacz pytanie Stackoverflow dla szczegółów: http://stackoverflow.com/questions/20998816/dot-character-in-mvc-web-api-2-for-request-such-as-api-people-staff-45287 –

Powiązane problemy