252 votes

Télécharger des fichiers de tout type dans MVC Asp.Net à l’aide de FileResult ?

J'ai eu il m'a suggéré que je devrais utiliser FileResult pour permettre aux utilisateurs de télécharger des fichiers à partir de mon Asp.Net application MVC. Mais les seuls exemples de ce que je peux trouver a toujours à voir avec les fichiers d'image (en spécifiant le type de contenu de l'image/jpeg).

Mais que faire si je ne peux pas savoir le type de fichier? Je veux que les utilisateurs puissent télécharger pratiquement n'importe quel fichier à partir de la filearea de mon site.

J'avais lu une méthode de le faire (voir un post précédent pour le code), qui fonctionne réellement bien, sauf pour une chose: le nom du fichier qui vient dans la boîte de dialogue Enregistrer sous est concaténé à partir du chemin d'accès au fichier avec des traits de soulignement (folder_folder_file.ext). Aussi, il semble que les gens pense que je devrais retourner un FileResult au lieu d'utiliser cette classe personnalisée que j'avais trouvé BinaryContentResult.

Quelqu'un sait la "bonne" façon de faire un téléchargement en MVC?

EDIT: J'ai eu la réponse (ci-dessous), mais juste pensé que je devrais poster le travail plein de code si quelqu'un d'autre est intéressé:

public ActionResult Download(string filePath, string fileName)
{
    string fullName = Path.Combine(GetBaseDir(), filePath, fileName);

    byte[] fileBytes = GetFile(fullName);
    return File(
        fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}

byte[] GetFile(string s)
{
    System.IO.FileStream fs = System.IO.File.OpenRead(s);
    byte[] data = new byte[fs.Length];
    int br = fs.Read(data, 0, data.Length);
    if (br != fs.Length)
        throw new System.IO.IOException(s);
    return data;
}

467voto

Ian Henry Points 9239

Vous pouvez simplement spécifier le type MIME générique octet-stream :

110voto

Jonathan Points 197

Le MVC framework prend en charge ce mode natif. Le Système De.Web.MVC.Le contrôleur.Fichier contrôleur fournit des méthodes pour renvoyer un fichier par nom/stream/matrice.

Par exemple à l'aide d'un chemin d'accès virtuel au fichier, vous pouvez effectuer les opérations suivantes.

return File(virtualFilePath, System.Net.Mime.MediaTypeNames.Application.Octet,  Path.GetFileName(virtualFilePath));

41voto

Si vous utilisez .NET Framework 4.5 alors vous utilisez utilisez le MimeMapping.GetMimeMapping (ByVal FileName As string) pour obtenir le Type MIME pour votre fichier. Voilà comment je l’ai utilisé dans mon action.

13voto

Manaf Abu.Rous Points 1589

Phil Haack a un bel article où il a créé un Custome Téléchargement de Fichier de Résultat Action de classe. Vous avez seulement besoin de spécifier le chemin d'accès virtuel du fichier et le nom à enregistrer en tant que.

Je l'ai utilisé une fois et voici mon code.

        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Download(int fileID)
        {
            Data.LinqToSql.File file = _fileService.GetByID(fileID);

            return new DownloadResult { VirtualPath = GetVirtualPath(file.Path),
                                        FileDownloadName = file.Name };
        }

Dans mon exemple, j'ai été de stocker le chemin d'accès physique des fichiers donc j'ai utilisé cette méthode d'assistance -que j'ai trouvé quelque part je ne me souviens pas à le convertir en un chemin d'accès virtuel

        private string GetVirtualPath(string physicalPath)
        {
            string rootpath = Server.MapPath("~/");

            physicalPath = physicalPath.Replace(rootpath, "");
            physicalPath = physicalPath.Replace("\\", "/");

            return "~/" + physicalPath;
        }

Voici l'intégralité de la classe à partir de Phill Haack de l'article

public class DownloadResult : ActionResult {

    public DownloadResult() {}

    public DownloadResult(string virtualPath) {
        this.VirtualPath = virtualPath;
    }

    public string VirtualPath {
        get;
        set;
    }

    public string FileDownloadName {
        get;
        set;
    }

    public override void ExecuteResult(ControllerContext context) {
        if (!String.IsNullOrEmpty(FileDownloadName)) {
            context.HttpContext.Response.AddHeader("content-disposition", 
            "attachment; filename=" + this.FileDownloadName)
        }

        string filePath = context.HttpContext.Server.MapPath(this.VirtualPath);
        context.HttpContext.Response.TransmitFile(filePath);
    }
}

8voto

Clark Kent Points 5845

Merci à Ian Henry!

En cas si vous avez besoin pour obtenir le fichier à partir de MS SQL Server ici est la solution.

Où est AppModelmodèle et **MyFiles** présente *table* dans votre base de données. **FileData** est dans le tableau MyFiles .

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