Je rencontre un problème lors de l'envoi de fichiers stockés dans une base de données à 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 mimetype envoyé au navigateur déterminer comment il doit être géré, et l'autre pour forcer un téléchargement.
Si je choisis d'afficher 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 défaut de comportement de téléchargement. Cependant, si je choisis d'afficher un fichier appelé SomeRandomFile.pdf
ou si 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 de pouvoir 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 de nom de fichier par défaut, donc les fichiers inconnus se voient attribuer un nom de fichier basé sur l'URL (qui ne connaît pas l'extension à donner en fonction du 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?
MISE À JOUR:
Cette question semble toucher beaucoup de monde, alors j'ai pensé publier une mise à jour. L'avertissement sur la réponse acceptée ci-dessous qui a été ajouté par Oskar concernant les caractères internationaux est complètement valide, et je l'ai frappé plusieurs fois en raison de l'utilisation de la ContentDisposition
classe. J'ai depuis mis à jour mon implémentation pour résoudre ce problème. Bien que le code ci-dessous provienne de ma dernière incarnation de ce problème dans une application ASP.NET Core (Full Framework), il devrait également fonctionner avec des modifications minimales dans une ancienne application MVC puisque j'utilise la System.Net.Http.Headers.ContentDispositionHeaderValue
classe.
using System.Net.Http.Headers;
public IActionResult Download()
{
Document document = ... //Obtain document from database context
//"attachment" means always prompt the user to download
//"inline" means let the browser try and handle it
var cd = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = document.FileName
};
Response.Headers.Add(HeaderNames.ContentDisposition, cd.ToString());
return File(document.Data, document.ContentType);
}
// an entity class for the document in my database
public class Document
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Data { get; set; }
//Other properties left out for brevity
}
la source
Inline = true
assurez-vous de NE PAS utiliser la surcharge à 3 paramètresFile()
qui prend le nom de fichier comme 3e paramètre. Il va travailler dans IE, mais Chrome signale un en- tête en double et refuser de présenter l'image.J'ai eu des problèmes avec la réponse acceptée car aucun type ne faisait allusion à la variable "document":
var document = ...
je publie donc ce qui a fonctionné pour moi au cas où quelqu'un d'autre aurait des problèmes.la source
AppDomain.CurrentDomain.BaseDirectory
estSystem.Web.HttpContext.Current.Server.MapPath("~")
, cela peut mieux fonctionner sur un vrai serveur par rapport à une machine locale.La réponse de Darin Dimitrov est correcte. Juste un ajout:
Response.AppendHeader("Content-Disposition", cd.ToString());
peut entraîner l'échec du rendu du fichier par le navigateur si votre réponse contient déjà un en-tête "Content-Disposition". Dans ce cas, vous pouvez utiliser:la source
pdf
fichier, si je définit le type de contenu commeSystem.Net.Mime.MediaTypeNames.Application.Octet
, il forcera le téléchargement même lorsque je le définiraiInline = true
, mais si je le définit commeResponse.ContentType = MimeMapping.GetMimeMapping(filePath)
, c'est-à-application/pdf
dire qu'il peut s'ouvrir correctement plutôt que de le téléchargerResponse.Headers.Add
nécessite le mode pipeline intégré IIS. De plus, même si le pool d'applications est défini comme intégré, il lèvera une exception. Solution. UtilisezResponse.AddHeader
. Voir le fil SO: stackoverflow.com/questions/22313167/…Pour visualiser le fichier (txt par exemple):
Pour télécharger un fichier (txt par exemple):
note: pour télécharger le fichier, nous devons passer l' argument fileDownloadName
la source
Inline
propriété sur Content-Disposition me permet de séparer la possibilité de définir le nom de fichier du comportement de forcer le téléchargement ou non.Je crois que cette réponse est plus propre, (basée sur https://stackoverflow.com/a/3007668/550975 )
la source
application/octet-stream
et cela a toujours causé le téléchargement du fichier plutôt que son affichage, et il semble être compatible.FileVirtualPath -> Research \ Global Office Review.pdf
la source
Le code ci-dessous a fonctionné pour moi pour obtenir un fichier pdf à partir d'un service API et le répondre au navigateur - j'espère que cela aide;
la source
Microsoft.AspNetCore.StaticFiles.FileExtensionContentTypeProvider
La méthode d'action doit renvoyer FileResult avec un flux, un octet [] ou un chemin virtuel du fichier. Vous devrez également connaître le type de contenu du fichier en cours de téléchargement. Voici un exemple de méthode utilitaire (rapide / sale). Exemple de lien vidéo Comment télécharger des fichiers à l'aide du noyau asp.net
la source
Si, comme moi, vous avez abordé ce sujet via les composants Razor pendant que vous apprenez Blazor, vous constaterez que vous devez réfléchir un peu plus en dehors de la boîte pour résoudre ce problème. C'est un peu un champ de mines si (également comme moi) Blazor est votre première incursion dans le monde de type MVC, car la documentation n'est pas aussi utile pour de telles tâches `` subalternes ''.
Donc, au moment de la rédaction, vous ne pouvez pas y parvenir en utilisant vanilla Blazor / Razor sans incorporer un contrôleur MVC pour gérer la partie de téléchargement de fichier dont un exemple est comme ci-dessous:
Ensuite, assurez-vous que le démarrage de votre application (Startup.cs) est configuré pour utiliser correctement MVC et que la ligne suivante est présente (ajoutez-la sinon):
.. et enfin modifier votre composant pour le lier au contrôleur, par exemple (exemple basé sur des itérations utilisant une classe personnalisée):
J'espère que cela aidera quiconque a eu du mal (comme moi!) À obtenir une réponse appropriée à cette question apparemment simple dans le royaume de Blazor…!
la source