2014-05-20 14 views
11

Ho una funzione accessibile tramite la mia API REST, configurata con ASP.NET Web API 2.1, che dovrebbe restituire un'immagine al chiamante. A scopo di test, ho appena restituito un'immagine di esempio che ho memorizzato sul mio computer locale in questo momento. Ecco il metodo:Perché il mio file non viene restituito da una richiesta GET dalla funzione API Web?

public IHttpActionResult GetImage() 
     { 
      FileStream fileStream = new FileStream("C:/img/hello.jpg", FileMode.Open); 
      HttpContent content = new StreamContent(fileStream); 
      content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg"); 
      content.Headers.ContentLength = fileStream.Length; 
      return Ok(content); 
     } 

Quando viene chiamato questo metodo, non riesco affatto a ottenere un'immagine. Ecco la risposta che sto ricevendo:

{"Intestazioni": [{"Chiave": "Tipo di contenuto", "Valore": ["immagine/jpeg"]}, {"Chiave": " Content-Length "," Value ": [" 30399 "]}]}

Perché non riesco a recuperare i dati dell'immagine come parte della richiesta? Come può essere risolto?

risposta

22

Una possibilità è quella di scrivere un personalizzato IHttpActionResult per gestire le vostre immagini:

public class FileResult : IHttpActionResult 
{ 
    private readonly string filePath; 
    private readonly string contentType; 

    public FileResult(string filePath, string contentType = null) 
    { 
     this.filePath = filePath; 
     this.contentType = contentType; 
    } 

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) 
    { 
     return Task.Run(() => 
     { 
      var response = new HttpResponseMessage(HttpStatusCode.OK) 
      { 
       Content = new StreamContent(File.OpenRead(filePath)) 
      }; 

      var contentType = this.contentType ?? MimeMapping.GetMimeMapping(Path.GetExtension(filePath)); 
      response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType); 

      return response; 
     }, cancellationToken); 
    } 
} 

che si potrebbe usare nella vostra azione di controllo Web API:

public IHttpActionResult GetImage() 
{ 
    return new FileResult(@"C:\\img\\hello.jpg", "image/jpeg"); 
} 
+5

perché non possono fornire solo questo fuori dalla scatola ?! – Greg

+1

È necessario 'Task.Run'? Non sarà sufficiente "Task.FromResult"? – Athari

+0

@Squidward Mentre Task.FromResult dovrebbe funzionare, credo che Task.Run potrebbe essere leggermente più vantaggioso in questo caso poiché consentirebbe la lettura del file in un'attività separata. Task.Run accetta anche la cancellazioneToken quindi potrebbero esserci dei benefici anche lì. – Scott

4

Aggiungendo a ciò che menziona @Darin, il L'helper Ok<T>(T content) che si sta utilizzando effettivamente restituisce uno OkNegotiatedContentResult<T>, che come indica il nome esegue la negoziazione del contenuto. Poiché in questo caso non si desidera la negoziazione del contenuto, è necessario creare un risultato di azione personalizzato.

Di seguito è riportato un esempio di come si può fare: http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/ActionResults/ActionResults/Results/OkFileDownloadResult.cs

-1

È possibile scaricare il file dal seguente codice:

HttpResponse response = HttpContext.Current.Response; 
    response.Clear(); 
    response.Buffer = false; 
    response.BufferOutput = false; 
    response.Charset = "UTF-8"; 
    response.ContentEncoding = System.Text.Encoding.UTF8;   
    response.AppendHeader("Content-disposition", "attachment; filename=" + fileName); 
    response.Write(excelXml); 
    response.Flush(); 
    response.End(); 
    HttpContext.Current.Response.End(); 
-1

È possibile utilizzare seguente codice per il download del file dal web api:

HttpResponseMessage objResponse = Request.CreateResponse(HttpStatusCode.OK);    
objResponse.Content = new StreamContent(new FileStream(HttpContext.Current.Server.MapPath("~/FolderName/" + FileName), FileMode.Open, FileAccess.Read)); 
objResponse.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
objResponse.Content.Headers.ContentDisposition.FileName = FileName; 
return objResponse; 
Problemi correlati