2013-06-05 20 views
6

Sto sperimentando un servizio API Web. Sto cercando di scaricare un file tramite una richiesta GET. Il metodo si accende bene e raggiunge il punto di rottura. Creo una risposta e la restituisco. Quindi, stranamente, il punto di interruzione si ripercuote. Sto usando il poster aggiuntivo di Firefox per testarlo. Il poster dice che non c'è risposta dal server. Qualche idea sul perché stia succedendo?Perché questo metodo dell'API Web viene attivato due volte?

Ecco il codice di creazione di risposta:

HttpResponseMessage result = this.Request.CreateResponse(HttpStatusCode.OK); 
result.Content = new StreamContent(stream); 
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
result.Content.Headers.ContentLength = file.Length; 
result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddDays(-1)); 
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Attachment") { FileName = file.Name }; 
return result; 

L'unico cambiamento significativo (mi viene in mente) è al mio WebApiConfig in questo modo:

config.Routes.MapHttpRoute(
name: "DefaultApi", 
routeTemplate: "api/{controller}/{action}/{id}", 
defaults: new { id = RouteParameter.Optional }); 

mia firma del metodo è simile al seguente: public HttpResponseMessage GetUpdate (int Id)

Tutte le altre mie azioni funzionano correttamente. Mi manca qualcosa sul lato client, come un'intestazione di accettazione o qualcosa del genere? Sto solo facendo un semplice GET adesso.

Grazie!

+0

Se provo il metodo e creo solo una risposta OK e lo restituisco, esso restituisce correttamente. Ho un Entity Framework usando block e un FileStream usando il blocco in là. Inizierò a estrarre il codice e vedere se riesco a isolare il problema. –

risposta

5

Trovato! L'affermazione usando sembra essere il problema. Lo stream verrà probabilmente eliminato prima che il risultato possa essere inviato. Ho aggiornato il mio codice in questo modo e ha iniziato a funzionare:

var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 

result.Content = new StreamContent(stream); 
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
result.Content.Headers.ContentLength = stream.Length; 
result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now.AddDays(-1)); 
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("Attachment") { FileName = Path.GetFileName(filePath) }; 
+1

btw, non è necessario impostare l'intestazione ContentLength in modo esplicito. –

+0

Era disponibile e facile da fare. C'è un vantaggio nel non inviarlo? L'ho messo lì per abitudine. Ho letto che ContentLength consente al browser di visualizzare un'accurata barra di avanzamento del download, anche se, in questo caso, un servizio di Windows è il consumatore di questo servizio web. –

+1

StreamContent imposta l'intestazione della lunghezza del contenuto per te. StreamContent controlla lo stream fornito per vedere se può cercare lo stream e quindi cerca di ottenere la lunghezza del flusso. –

Problemi correlati