Amener PdfStamper à fonctionner avec MemoryStreams (c #, itextsharp)

Il m’est venu de retravailler l’ancien code qui insère les fichiers PDF dans un nouveau, qui signe les MemoryStreams (tableaux de octets) envoyés et envoyés par des services Web. Simple, non? C’était hier. Aujourd’hui, je ne peux tout simplement pas le faire fonctionner.

Ceci est l’ancien code, qui utilise FileStreams et cela fonctionne:

public static ssortingng OldPdfSigner(PdfReader pdfReader, ssortingng destination, ssortingng password, ssortingng reason, ssortingng location, ssortingng pathToPfx) { using (FileStream pfxFile = new FileStream(pathToPfx, FileMode.Open, FileAccess.Read)) { ... using (PdfStamper st = PdfStamper.CreateSignature(pdfReader, new FileStream(destination, FileMode.Create, FileAccess.Write), '\0')) { PdfSignatureAppearance sap = st.SignatureAppearance; sap.SetCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.Reason = reason; sap.Location = location; return destination; } } } 

Ci-dessous se trouve ce que je me suis refait: une exception System.ObjectDisposedException: Impossible d’accéder à un stream fermé.

  public static byte[] PdfSigner(PdfReader pdfReader, ssortingng password, ssortingng reason, ssortingng location, ssortingng pathToPfx) { using (FileStream pfxFile = new FileStream(pathToPfx, FileMode.Open, FileAccess.Read)) { ... MemoryStream outputStream = new MemoryStream(); using (PdfStamper st = PdfStamper.CreateSignature(pdfReader, outputStream, '\0')) { st.Writer.CloseStream = false; PdfSignatureAppearance sap = st.SignatureAppearance; sap.SetCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.Reason = reason; sap.Location = location; st.Close(); outputStream.Position = 0; return outputStream.ToArray(); } } } 

et si je commente

 st.Close(); 

cela crée un document vide. Qu’est-ce que je fais mal?

Ce n’est pas spécifique à votre code de signature, mais lorsque vous PdfStamper MemoryStream et PdfStamper , suivez ce modèle général:

 using (MemoryStream ms = new MemoryStream()) { using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) { // do stuff } return ms.ToArray(); } 
  • MemoryStream implémente IDisposable , incluez donc une instruction using .
  • L’ PdfStamper using PdfStamper prend en charge la PdfStamper de l’object. Vous n’avez donc pas besoin d’appeler Close() ni de définir la propriété CloseStream .
  • Votre extrait de code renvoie le tableau d’octets trop tôt , à l’intérieur de l’ PdfStamper using , de sorte que votre MemoryStream est effectivement un no-op. Renvoie le tableau d’octets en dehors de l’ PdfStamper using et à l’ intérieur de l’instruction MemoryStream using .
  • Généralement, il n’est pas nécessaire de réinitialiser la propriété Position MemoryStream .
  • Ignorez le constructeur PdfStamper ci-dessus – il provient d’un code de test que j’avais pour remplir des formulaires et utilisez le constructeur / la méthode dont vous avez besoin pour signer.