8
votes

Essayer de diffuser un fichier PDF avec ASP.NET produise un "fichier endommagé"

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.

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).

Question 1: Qu'est-ce que je fais mal? Question 2: Puis-je télécharger des fichiers volumineux en utilisant cette approche? xxx


5 commentaires

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 :(


6 Réponses :


0
votes

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.

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.

  • Après l'appel de ClearContent, j'appelle Clearheaders ();
  • Je ne spécifie pas de longueur.
  • Je ne spécifie pas en ligne sur la disposition
  • Je sais que tout le monde dit de ne pas le faire, mais j'ai une réponse.flush (); suivi de la réponse.Close ();

    Et, une autre chose, vérifiez votre valeur de contenuType pour vous assurer qu'elle est correcte pour les PDFS (("Application / PDF").


0 commentaires

7
votes

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é. xxx


3 commentaires

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



1
votes

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();


0 commentaires

7
votes

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);
}


0 commentaires

0
votes

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);


0 commentaires

0
votes

Cet extrait comprend le code de lecture dans le fichier à partir d'un chemin de fichier et extraire le nom du fichier: xxx


4 commentaires

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?