Retourner un fichier à View / Download dans ASP.NET MVC

Je rencontre un problème lors de l’envoi de fichiers stockés dans une firebase database à l’utilisateur dans ASP.NET MVC. Ce que je veux, c’est une vue répertoriant deux liens, l’un pour afficher le fichier et laisser le type MIME envoyé au navigateur déterminer comment il doit être géré, et l’autre pour forcer le téléchargement.

Si je choisis de voir un fichier appelé SomeRandomFile.bak et que le navigateur n’a pas de programme associé pour ouvrir des fichiers de ce type, je n’ai aucun problème avec le comportement de téléchargement. Cependant, si je choisis de voir un fichier nommé SomeRandomFile.pdf ou SomeRandomFile.jpg je souhaite que le fichier s’ouvre simplement. Mais je veux également garder un lien de téléchargement sur le côté afin que je puisse forcer une invite de téléchargement quel que soit le type de fichier. Est-ce que ça a du sens?

J’ai essayé FileStreamResult et cela fonctionne pour la plupart des fichiers, son constructeur n’accepte pas un nom de fichier par défaut, donc les fichiers inconnus se voient atsortingbuer un nom de fichier basé sur l’url (qui ne connaît pas l’extension à atsortingbuer au type de contenu). Si je force le nom du fichier en le spécifiant, je perds la possibilité pour le navigateur d’ouvrir le fichier directement et j’obtiens une invite de téléchargement. Quelqu’un d’autre a-t-il rencontré cela?

Ce sont les exemples de ce que j’ai essayé jusqu’à présent.

 //Gives me a download prompt. return File(document.Data, document.ContentType, document.Name); 

 //Opens if it is a known extension type, downloads otherwise (download has bogus name and missing extension) return new FileStreamResult(new MemoryStream(document.Data), document.ContentType); 

 //Gives me a download prompt (lose the ability to open by default if known type) return new FileStreamResult(new MemoryStream(document.Data), document.ContentType) {FileDownloadName = document.Name}; 

Aucune suggestion?

 public ActionResult Download() { var document = ... var cd = new System.Net.Mime.ContentDisposition { // for example foo.bak FileName = document.FileName, // always prompt the user for downloading, set to true if you want // the browser to try to show the file inline Inline = false, }; Response.AppendHeader("Content-Disposition", cd.ToSsortingng()); return File(document.Data, document.ContentType); } 

REMARQUE: Cet exemple de code ci-dessus ne parvient pas à prendre en compte correctement les caractères internationaux dans le nom de fichier. Voir RFC6266 pour la normalisation pertinente. Je crois que les versions récentes de la méthode File() de ASP.Net MVC et de la classe ContentDispositionHeaderValue correctement ContentDispositionHeaderValue compte. – Oskar 2016-02-25

J’ai eu des problèmes avec la réponse acceptée en raison de l’absence de suggestion sur la variable “document”: var document = ... Je poste donc ce qui a fonctionné pour moi en cas de problème.

 public ActionResult DownloadFile() { ssortingng filename = "File.pdf"; ssortingng filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename; byte[] filedata = System.IO.File.ReadAllBytes(filepath); ssortingng contentType = MimeMapping.GetMimeMapping(filepath); var cd = new System.Net.Mime.ContentDisposition { FileName = filename, Inline = true, }; Response.AppendHeader("Content-Disposition", cd.ToSsortingng()); return File(filedata, contentType); } 

Pour afficher le fichier (txt par exemple):

 return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain); 

Pour télécharger le fichier (txt par exemple):

 return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain, "TextFile.txt"); 

note: pour télécharger le fichier, nous devrions passer l’argument fileDownloadName

La réponse de Darin Dimitrov est correcte. Juste un ajout:

Response.AppendHeader("Content-Disposition", cd.ToSsortingng()); Le navigateur peut échouer lors du rendu du fichier si votre réponse contient déjà un en-tête “Content-Disposition”. Dans ce cas, vous pouvez utiliser:

 Response.Headers.Add("Content-Disposition", cd.ToSsortingng()); 

FileVirtualPath -> Research \ Global Office Review.pdf

 public virtual ActionResult GetFile() { return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath)); } 

Je crois que cette réponse est plus propre (basée sur https://stackoverflow.com/a/3007668/550975 )

  public ActionResult GetAttachment(long id) { FileAttachment attachment; using (var db = new TheContext()) { attachment = db.FileAttachments.FirstOrDefault(x => x.Id == id); } return File(attachment.FileData, "application/force-download", Path.GetFileName(attachment.FileName)); } 

Le code ci-dessous a fonctionné pour moi pour obtenir un fichier pdf à partir d’un service API et y répondre au navigateur.

 public async Task PrintPdfStatements(ssortingng fileName) { var fileContent = await GetFileStreamAsync(fileName); var fileContentBytes = ((MemoryStream)fileContent).ToArray(); return File(fileContentBytes, System.Net.Mime.MediaTypeNames.Application.Pdf); } 

Un autre moyen facile est

 public ActionResult GetLoadingLogo() { if (1 == 1) { return new FilePathResult(Server.MapPath("~/Content/Images/ajaxLoader_dhanlaxmi.gif"), "image/gif"); } else { return new FilePathResult(Server.MapPath("~/Content/Images/add-icon.png"), "image/png"); } }