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

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

  • FileContentResult: envoie le contenu d’un fichier binary à la réponse.
  • FilePathResult: envoie le contenu d’un fichier à la réponse
  • FileResult: Retourne la sortie binary à écrire dans la réponse
  • FileStreamResult: envoie du contenu binary à la réponse en utilisant une instance Stream

Ces descriptions proviennent de MSDN et à l’exception de FileStreamResult, les trois premiers sons sont identiques. Alors, quelle est la différence entre eux?

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

  • FileContentResult – vous l’utilisez lorsque vous souhaitez retourner un tableau d’octets en tant que fichier
  • FilePathResult – lorsque vous avez un fichier sur le disque et que vous souhaitez renvoyer son contenu (vous donnez un chemin)
  • FileStreamResult – vous avez un stream ouvert, vous voulez retourner son contenu sous forme de fichier

Cependant, vous devrez rarement utiliser ces classes – vous pouvez simplement utiliser l’une des surcharges de Controller.File et laisser asp.net mvc faire la magie pour vous

Bonne question … et mérite plus de détails. Je me trouve ici en raison d’une situation intéressante. Nous livrions des pièces jointes 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». Ouais … vous l’avez compris … le tout. Donc, on pourrait le réécrire pour qu’il soit simplement «pdf» et le fichier serait toujours sauvegardé intact, mais quel gâchis!

Donc, pour décrire la situation initiale, nous avons paramétré l’en-tête ‘Content-Disposition’ puis renvoyé un fichier FileContentResult …

 var cd = new System.Net.Mime.ContentDisposition { FileName = result.Attachment.FileName, Inline = false }; Response.AppendHeader("Content-Disposition", cd.ToSsortingng()); return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName); 

Semblait bon. A bien fonctionné dans IE. J’ai donc fait quelques recherches et essayé d’implémenter FileStreamResult à la place (en conservant 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)); 

Il a résolu le problème dans Chrome! Hmmm … mais pourquoi diable devrais-je prendre mon bon tableau d’octets et le diffuser, puis le renvoyer pour que le nom du fichier fonctionne correctement?

Puis vint le violoneux.

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

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

Réaction étrange … mais certainement une bonne à savoir.