Qual è la differenza tra i quattro risultati dei file in ASP.NET MVC


136

ASP.NET ha quattro diversi tipi di risultati di file:

  • FileContentResult: invia il contenuto di un file binario alla risposta.
  • FilePathResult: invia il contenuto di un file alla risposta
  • FileResult: restituisce un output binario da scrivere nella risposta
  • FileStreamResult: invia il contenuto binario alla risposta utilizzando un'istanza Stream

Queste descrizioni sono prese da MSDN e, ad eccezione di FileStreamResult, i primi tre suonano identici. Quindi qual è la differenza tra loro?

Risposte:


176

FileResult è una classe base astratta per tutti gli altri.

  • FileContentResult - lo usi quando hai un array di byte che desideri restituire come file
  • FilePathResult - quando si dispone di un file sul disco e si desidera restituire il contenuto (si fornisce un percorso)
  • FileStreamResult - hai uno stream aperto, vuoi restituire il suo contenuto come file

Tuttavia, raramente dovrai usare queste classi: puoi semplicemente usare uno dei Controller.Filesovraccarichi e lasciare che ASP.NET MVC faccia la magia per te.


29

Ottima domanda ... e merita maggiori dettagli. Mi trovo qui come risultato di una situazione interessante. Fornivamo alcuni allegati pdf tramite l'ambiente MVC3 / C #. Il nostro codice è stato rilasciato e abbiamo iniziato a ricevere alcune risposte dai nostri clienti sul fatto che i download si stavano comportando in modo strano quando utilizzavano Chrome e il tipo di file veniva convertito in "pdf- ,legato.pdf-, allegato". Sì ... hai capito ... tutto. Quindi, si potrebbe riscriverlo in 'pdf' e il file verrebbe comunque salvato intatto, ma che casino!

Quindi, per descrivere la situazione iniziale, stavamo impostando l'intestazione "Content-Disposition", quindi restituendo un FileContentResult ...

var cd = new System.Net.Mime.ContentDisposition
            {
                FileName = result.Attachment.FileName,
                Inline = false
            };
            Response.AppendHeader("Content-Disposition", cd.ToString());

return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);

Sembrava buono. Ha funzionato bene in IE. Quindi ho fatto qualche ricerca e ho provato ad implementare FileStreamResult (mantenendo il setter Content-Disposition):

MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));

Risolto il problema in Chrome! Hmmm ... ma perché diamine dovrei prendere il mio array di byte perfettamente funzionante e trasmetterlo in streaming e poi restituirlo tramite questo per far funzionare correttamente il nome del file?

Poi venne il violinista.

Con FileContentResult, ho ottenuto 2 disposizioni di contenuto nell'intestazione. Con FileStreamResult, ho ottenuto 1.

FileContentResult aggiunge un'intestazione Content-Disposition quando fornisce il Nome file e Chrome considera i multipli di questa intestazione come un errore.

Strana reazione ... ma sicuramente una buona da sapere.


3
Solo un consiglio, in .NET 4+ puoi usare System.Web.MimeMapping.GetMimeMapping(filename)per raccogliere il tipo mime se non riesci ad accedervi facilmente.
GONeale,

4
Fornire un nome file a un Filerisultato significa impostare la sua FileDownloadNameproprietà, che imposta le Content-Dispositionintestazioni per te. E supporta correttamente i nomi dei file utf-8, che non ContentDispositionaiutano la classe (vedi il mio commento qui per maggiori dettagli).
Frédéric,

1
Sì, grazie @ Frédéric, tu da solo tra tutti i post di SO mi hai spiegato cosa stava succedendo!
Nacht,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.