140 votes

Quelle est la différence entre les quatre résultats de fichier dans ASP.NET MVC ?

ASP.NET dispose de quatre types différents de résultats de fichiers :

  • FileContentResult : Envoie le contenu d'un fichier binaire à la réponse.
  • FilePathResult : Envoie le contenu d'un fichier à la réponse
  • FileResult : Retourne la sortie binaire à écrire dans la réponse.
  • FileStreamResult : Envoie un contenu binaire à la réponse en utilisant une instance Stream

Ces descriptions sont tirées de MSDN et, à l'exception du FileStreamResult, les trois premières sont identiques. Quelle est donc la différence entre elles ?

185voto

maciejkow Points 4504

FileResult est une classe de base abstraite pour toutes les autres.

  • FileContentResult - vous l'utilisez lorsque vous avez un tableau d'octets que vous souhaitez renvoyer sous forme de fichier.
  • FilePathResult - lorsque vous avez un fichier sur le disque et que vous souhaitez retourner son contenu (vous donnez un chemin)
  • FileStreamResult - vous avez un flux ouvert, vous voulez renvoyer son contenu sous forme de fichier

Cependant, vous aurez rarement besoin d'utiliser ces classes - vous pouvez simplement utiliser l'une des classes suivantes Controller.File et laissez ASP.NET MVC faire la magie pour vous.

30voto

beauXjames Points 1565

Excellente question... et qui mérite plus de détails. Je me retrouve ici à la suite d'une situation intéressante. Nous livrions des pièces jointes en pdf via l'environnement MVC3/C#. Notre code a été publié et nous avons commencé à recevoir des réponses de nos clients indiquant que les téléchargements se comportaient étrangement lorsqu'ils utilisaient Chrome et que le type de fichier était converti en "pdf-, attachment.pdf-, attachment". Ouaip... vous l'avez compris... tout ça. On peut donc le réécrire pour qu'il ne soit plus que "pdf" et que le fichier soit enregistré intact, mais quel gâchis !

Donc, pour décrire la situation initiale, nous définissions l'en-tête "Content-Disposition" et retournions 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);

Ça semblait bon. Ça marchait bien dans IE. J'ai donc fait quelques recherches et j'ai essayé d'implémenter FileStreamResult à la place (en gardant le 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));

Le problème a été résolu dans Chrome ! Hmmm... mais pourquoi diable devrais-je prendre mon tableau d'octets, le streamer et le renvoyer via ceci pour que le nom du fichier fonctionne correctement ?

Puis vint le violoniste.

Avec FileContentResult, j'ai obtenu 2 Content-Dispositions dans l'en-tête. Avec FileStreamResult, j'ai obtenu 1.

FileContentResult ajoute un en-tête Content-Disposition lorsqu'il fournit le nom du fichier et Chrome considère les multiples de cet en-tête comme une erreur.

Une réaction étrange... mais certainement une qu'il est bon de savoir.

3 votes

Juste un conseil, dans .NET 4+ vous pouvez utiliser System.Web.MimeMapping.GetMimeMapping(filename) pour recueillir le type mime si vous ne pouvez pas y accéder facilement.

5 votes

Fournir un nom de fichier à un File signifie que l'on fixe son FileDownloadName qui définissent la propriété Content-Disposition les en-têtes pour vous. Et il prend correctement en charge les noms de fichiers utf-8, ce qui n'est pas le cas pour les noms de fichier. ContentDisposition (voir mon commentaire ici pour plus de détails).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X