8 votes

Response.TransmitFile Pas de téléchargement et pas d'erreur.

J'utilise actuellement une réponse HttpResponse pour télécharger des fichiers depuis mon serveur. J'ai déjà quelques fonctions utilisées pour télécharger des fichiers Excel/Word, mais j'ai des difficultés à télécharger mon simple fichier texte (.txt).

Avec le fichier texte, je vide le contenu d'une boîte de texte dans un fichier, j'essaie de télécharger le fichier avec la réponse HttpResponse, puis je supprime le fichier texte temporaire.

Voici un exemple de mon code qui fonctionne pour les documents Excel/Word :

protected void linkInstructions_Click(object sender, EventArgs e)
{
    String FileName = "BulkAdd_Instructions.doc";
    String FilePath = Server.MapPath("~/TempFiles/BulkAdd_Instructions.doc");
    System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
    response.ClearContent();
    response.Clear();
    response.ContentType = "application/x-unknown";
    response.AddHeader("Content-Disposition", "attachment; filename=" + FileName + ";");
    response.TransmitFile(FilePath);
    response.Flush();
    response.End();  
}

Et voici le morceau de code qui ne fonctionne pas.
Prenez note que le code s'exécute sans lancer d'erreurs. Le fichier est créé, puis supprimé, mais jamais transmis à l'utilisateur.

protected void saveLog(object sender, EventArgs e)
{ 
    string date = DateTime.Now.ToString("MM_dd_yyyy_hhmm");     //  Get Date/Time
    string fileName = "BulkLog_"+ date + ".txt";                //  Stitch File Name + Date/Time
    string logText = errorLog.Text;                             //  Get Text from TextBox
    string halfPath = "~/TempFiles/" + fileName;                //  Add File Name to Path
    string mappedPath = Server.MapPath(halfPath);               //  Create Full Path

    File.WriteAllText(mappedPath, logText);                     //  Write All Text to File

    System.Web.HttpResponse response = System.Web.HttpContext.Current.Response;
    response.ClearContent();
    response.Clear();
    response.ContentType = "text/plain";
    response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);
    response.TransmitFile(mappedPath);                //  Transmit File
    response.Flush();

    System.IO.File.Delete(mappedPath);                //  Delete Temporary Log
    response.End();
}

11voto

anthonyvscode Points 704

C'est parce que vous supprimez le fichier avant qu'il ne puisse être envoyé.

De MSDN - Méthode HttpResponse.End

Envoie toute la sortie actuellement mise en mémoire tampon à le client, arrête l'exécution de la page et déclenche l'événement EndRequest.

Essayez de mettre votre ligne System.IO.File.Delete(mappedPath) ; après la ligne response.End() ; dans mon test, il semble que cela fonctionne.

De plus, ce serait une bonne idée de vérifier d'abord si le fichier existe, je ne vois pas de file.Exists là-dedans, je ne veux pas d'exceptions de référence nulle, et de définir le Content-Length.

EDIT : voici le code que j'ai utilisé dans un projet au travail il y a quelque temps, cela pourrait vous aider un peu.

// Get the physical Path of the file
string filepath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath + folder + filename;

// Create New instance of FileInfo class to get the properties of the file being downloaded
FileInfo file = new FileInfo(filepath);

// Checking if file exists
if (file.Exists)
{                            
    // Clear the content of the response
    Response.ClearContent();

    // LINE1: Add the file name and attachment, which will force the open/cance/save dialog to show, to the header
    Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", file.Name));

    // Add the file size into the response header
    Response.AddHeader("Content-Length", file.Length.ToString());

    // Set the ContentType
    Response.ContentType = ReturnFiletype(file.Extension.ToLower());

    // Write the file into the response (TransmitFile is for ASP.NET 2.0. In ASP.NET 1.1 you have to use WriteFile instead)
    Response.TransmitFile(file.FullName);

    // End the response
    Response.End();

    //send statistics to the class
}

Et voici la méthode Filetype que j'ai utilisée

//return the filetype to tell the browser. 
//defaults to "application/octet-stream" if it cant find a match, as this works for all file types.
public static string ReturnFiletype(string fileExtension)
{
    switch (fileExtension)
    {
        case ".htm":
        case ".html":
        case ".log":
            return "text/HTML";
        case ".txt":
            return "text/plain";
        case ".doc":
            return "application/ms-word";
        case ".tiff":
        case ".tif":
            return "image/tiff";
        case ".asf":
            return "video/x-ms-asf";
        case ".avi":
            return "video/avi";
        case ".zip":
            return "application/zip";
        case ".xls":
        case ".csv":
            return "application/vnd.ms-excel";
        case ".gif":
            return "image/gif";
        case ".jpg":
        case "jpeg":
            return "image/jpeg";
        case ".bmp":
            return "image/bmp";
        case ".wav":
            return "audio/wav";
        case ".mp3":
            return "audio/mpeg3";
        case ".mpg":
        case "mpeg":
            return "video/mpeg";
        case ".rtf":
            return "application/rtf";
        case ".asp":
            return "text/asp";
        case ".pdf":
            return "application/pdf";
        case ".fdf":
            return "application/vnd.fdf";
        case ".ppt":
            return "application/mspowerpoint";
        case ".dwg":
            return "image/vnd.dwg";
        case ".msg":
            return "application/msoutlook";
        case ".xml":
        case ".sdxl":
            return "application/xml";
        case ".xdp":
            return "application/vnd.adobe.xdp+xml";
        default:
            return "application/octet-stream";
    }
}

5voto

Josh Harris Points 309

Je suis tombé sur cet article lors de mes recherches, et j'ai remarqué qu'il n'était pas utile pour nous dire pourquoi l'UpdatePanel a causé le problème en premier lieu.

L'UpdatePanel est un postback asynchrone, et Response.TransmitFile a besoin d'un postback complet pour fonctionner correctement.

Le contrôle qui déclenche le retour asynchrone doit devenir un déclencheur dans l'UpdatePanel :

<Triggers>        
<asp:PostBackTrigger ControlID="ID_of_your_control_that_causes_postback" />
</Triggers>

2voto

jfrax Points 21

Merci pour le suivi de votre problème. J'ai passé des heures à essayer de comprendre pourquoi aucun code d'erreur n'était envoyé alors que rien ne se passait. Il s'avère que c'était mon AJAX UpdatePanel qui se mettait mystérieusement et secrètement en travers du chemin.

1voto

J'ai résolu ce problème. Le site Réponse nécessite un retour complet afin de télécharger un fichier Excel généré sur le serveur mais le postback complet était empêché par l'interface de l'utilisateur. UpdatePanel sur mon formulaire web, qui contenait mon bouton d'exportation. Donc à l'intérieur du UpdatePanel tag, j'ai changé ça...

<asp:AsyncPostBackTrigger ControlID="btnExport" EventName="Click" />

...à ceci pour résoudre le problème :

<asp:PostBackTrigger ControlID="btnExport"/>

0voto

Faiz Points 1660

Essayez aussi ce pour enregistrer le texte du côté client (Chrome seulement maintenant) sans l'aller-retour vers le serveur.

Ici est une autre base de flash...

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