2010-02-24 8 views
0

Dans une application ASP.NET, j'utilise iTextSharp (PdfStamper, surtout) pour remplir un certain contenu sur un PDF et l'envoyer à l'utilisateur. Le code suivant est à l'intérieur d'un événement OnClick:Response.Stream sortie (un PDF) perdu par Adobe Reader

PdfReader r = new PdfReader(
    new RandomAccessFileOrArray(Request.MapPath(compatiblePdf)), null 
); 

ps = new PdfStamper(r, Response.OutputStream); 
AcroFields af = ps.AcroFields; 

af.SetField("ContactInfo[0]", o.mallName); 
af.SetField("ClientName", string.Format("{0} {1}", c.firstName, c.lastName)); 
af.SetField("ClientEmail", c.emailAddress); 
ps.FormFlattening = true; 
Response.ContentType = "application/pdf"; 
Response.AddHeader("Content-Disposition", "attachment; filename=Form.pdf"); 
ps.Close(); 
Response.End(); 

Donc, en gros, PdfReader obtient le fichier, PdfStamper prend le PdfReader comme argument, et poussera son PDF fini à Response.OutputStream.

Le problème est que, avec IE et Adobe Reader, si vous sélectionnez "Ouvrir" dans la boîte de dialogue, Adobe Reader affiche une erreur indiquant "Impossible de trouver le fichier". Les utilisateurs peuvent "enregistrer" le fichier tout à fait bien, et même commencer le téléchargement à nouveau (en cliquant sur "Ouvrir" à nouveau lorsque demandé) semble fonctionner. Mais sur une nouvelle machine qui n'a jamais téléchargé le fichier, Adobe Reader semble égarer le fichier entre celui-ci allant vers les fichiers temporaires ou tout ce que fait IE.

Je ne peux imaginer qu'une seule chose en ce moment: Response.End(), devrait, peut-être, être Response.Close() à la place, ou peut-être le tout devrait avoir Response.Flush() avant. Mais je ne sais pas avec certitude que cela ne va pas aggraver le problème, et j'ai du mal à tester (parce que, une fois que vous avez téléchargé le fichier une fois, l'erreur n'est pas renvoyée).

Cela peut-il résoudre le problème? Est-ce que j'ai quelque chose de mal dans les en-têtes? Ou y a-t-il autre chose que je devrais faire avec les objets Response/PdfStamper?

Répondre

5

Chaque fois que je force le contenu à un utilisateur, je suivre cet ensemble d'étapes pour la réponse:

Response.Clear() 
Response.ClearHeaders() 
Response.Buffer = True 
Response.ContentType = "your mime type" 
Response.CacheControl = "public" 
Response.AddHeader("Pragma", "public") 
Response.AddHeader("Expires", "0") 
Response.AddHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0") 
Response.AddHeader("Content-Description", "Description of your content") 
Response.AddHeader("Content-Disposition", "attachment; filename=""somefile.pdf""") 

' Add your content to the buffer here 

Response.Flush() 
Response.End() 

Cela semble être assez bonne à prévenir toutes les ordures « fichier non trouvé ».

EDIT: Pour ceux intéressés par ce que ces en-têtes signifient:

  1. Pragma: public aide cache de contrôle pour la compatibilité descendante avec les requêtes HTTP/1.0. Cela garantit que votre requête parvient au serveur même s'il existe déjà une réponse en cache.
  2. Expires: 0 est un intervalle en secondes après lequel la réponse expire. La mise à 0 expire la réponse immédiatement, évitant ainsi un cache périmé.
  3. Cache-control: must-revalidate indique au cache qu'il doit obéir à toutes vos commandes (c'est-à-dire qu'il doit vous donner une nouvelle réponse lorsque vous le demandez).
  4. Cache-control: post-check=0, pre-check=0: il s'agit d'un intervalle en secondes pendant lequel une réponse doit être vérifiée pour la fraîcheur avant/après la diffusion du contenu (respectivement). Le réglage sur 0 force la fraîcheur de la réponse à être vérifiée immédiatement. (More at MSDN.)
  5. Les autres décrivent simplement le contenu que vous voulez que l'utilisateur reçoive. La spécification de "pièce jointe" indique au navigateur d'offrir le fichier en téléchargement et de ne pas l'afficher en ligne.
+0

Une raison pour laquelle cela doit être fait? Cela fonctionne mais n'importe quelle raison spécifique? – tHeSiD

+0

J'ai mis à jour le post avec ce que je pouvais me rappeler ou déterrer. –

Questions connexes