Dans l'une de mes applications Web ASP.NET, j'ai besoin de masquer l'emplacement d'un fichier PDF servi aux utilisateurs.
Ainsi, j'écris une méthode qui récupère son contenu binaire de son emplacement sur un système CMS puis afflète une matrice d'octet sur l'utilisateur Web. P>
Je reçois, malheureusement, une erreur lorsque Téléchargement du flux: "Impossible d'ouvrir le fichier car il est endommagé" (ou quelque chose de similaire à celui-ci, lors de l'ouverture du fichier dans Adobe Reader). P>
Question 1: Qu'est-ce que je fais mal?
Question 2: Puis-je télécharger des fichiers volumineux en utilisant cette approche? P>
6 Réponses :
J'ai quelque chose de similaire travaillant sur un site Web actuel 2.0. Et je me souviens de lutter pour le faire travailler bien que cela ait été un moment donc je ne me souviens pas des luttes. P>
Il y a cependant quelques différences entre ce que vous avez ce que vous avez. Espérons que ceux-ci vous aideront à résoudre le problème. P>
Et, une autre chose, vérifiez votre valeur de contenuType pour vous assurer qu'elle est correcte pour les PDFS (("Application / PDF"). P>
Voici une méthode que j'utilise. Cela transmet une pièce jointe, c'est-à-dire que c'est-à-dire une boîte de dialogue OUVERT / SAVE. J'arrive également à savoir que les fichiers ne seront pas supérieurs à 1 m, je suis donc sûr qu'il y a un moyen plus propre de le faire.
J'ai eu un problème similaire avec les PDF, et j'ai réalisé que je devais absolument utiliser des ruisseaux binaires et relookbytes. Tout ce qui avec des chaînes est gâché. P>
Je ne sais pas quel peu de code a fait fonctionner, mais ça marche enfin :) Merci!
Utilisez-vous cela avec ReportViewer?
L'inconvénient de spécifier une certaine quantité d'octets est que tous ces octets seront écrits dans le flux, même si le fichier n'est pas aussi gros que cela. Vous pouvez simplement obtenir la longueur du flux et utiliser ce numéro à la place lorsque vous appelez Reader.ReadBytes
Cet extrait a fait pour moi:
Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.ContentType = mimeType; Response.AddHeader("Content-Disposition", "attachment"); Response.WriteFile(filePath); Response.Flush();
Les autres réponses copient le contenu du fichier en mémoire avant d'envoyer la réponse. Si les données sont déjà en mémoire, vous aurez deux copies, ce qui n'est pas très bon pour l'évolutivité. Cela peut mieux fonctionner à la place:
string filename = @"C:\dirs.txt"; using (FileStream fs = File.Open(filename, FileMode.Open)) { SendFile(fs, fs.Length, "application/octet-stream", filename); }
Lorsque vous utilisez votre code, vous copiez les octets de votre PDF directement dans votre réponse. Tous les codes ASCII spéciaux doivent être codés pour réussir HTTP. Lorsque vous utilisez la fonction de flux, le flux est codé afin de ne pas avoir à vous en soucier.
var bytes = new byte[contentLen]; stream.Read(bytes, 0, contentLen); stream.Close(); Response.BinaryWrite(bytes);
Cet extrait comprend le code de lecture dans le fichier à partir d'un chemin de fichier et extraire le nom du fichier:
Et il lit tout le fichier dans un tableau d'octets et laisse le fichier ouvert.
Quel changement recommanderiez-vous? À votre santé
Dois-je aussi appeler réponse.OutputStream.close ()?
Et puis-je envelopper l'ouverture du fichier dans une déclaration à l'aide d'une déclaration?
Pourquoi ne pas utiliser la méthode de réponse.writefile?
Le fichier n'existe pas vraiment dans le système de fichiers.
Pour être plus clair: le fichier existe dans la base de données CMS. C'est une URL adressable, mais je ne peux pas vraiment récupérer le fichier du système de fichiers.
Ah, j'ai raté cette partie. Que diriez-vous de supprimer la longueur du contenu? En outre, pourquoi devez-vous avoir String.Format ("Inline; FileName = fichier.pdf")?
Supprimer cela ne fait aucune différence malheureusement :(