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
. 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
. 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
. Position
MemoryStream
. 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.