Il m'est venu de retravailler l'ancien code qui signe PDF fichiers dans un nouveau, qui signe MemoryStreams (tableaux d'octets) qui viennent et sont envoyés par les services Web. Simple, non? Eh bien, c'était hier Aujourd'hui, je n'arrive pas à le faire fonctionner.
Ceci est l'ancien code, qui utilise FileStreams et cela fonctionne:
public static string OldPdfSigner(PdfReader pdfReader, string destination, string password, string reason, string location, string 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;
}
}
}
Voici ce que j'ai refait moi-même, ce qui lève System.ObjectDisposedException: Impossible d'accéder à un flux fermé.
public static byte[] PdfSigner(PdfReader pdfReader, string password, string reason, string location, string 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();
il crée un document vide. Qu'est-ce que je fais mal?
Non spécifique à votre code de signature, mais lorsque vous travaillez avec MemoryStream
et PdfStamper
, suivez ce schéma 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
, donc incluez une instruction using
.PdfStamper
using
s'occupe de supprimer l'objet, vous n'avez donc pas besoin d'appeler Close()
, et vous n'avez pas besoin de définir CloseStream
propriété.PdfStamper
using
, de sorte que votre MemoryStream
est en fait un no-op. Renvoie le tableau d'octets extérieur de l'instruction PdfStamper
using
, et intérieur la MemoryStream
using
déclaration.MemoryStream
Position
.PdfStamper
ci-dessus - il s'agit d'un code de test que j'avais pour remplir les formulaires et utilisez le constructeur/la méthode dont vous avez besoin pour faire votre signature.