Domanda

Using iTextSharp 5.3.4.0, I'm having difficulty working with PdfStamper and MemoryStream.

The MemoryStream is always empty.

    PdfReader pdfReader = new PdfReader(Server.MapPath(@"Document.pdf"));

    MemoryStream memoryStream = new MemoryStream();

    PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, memoryStream, '\0');

    //...

    pdfStamper.Writer.CloseStream = false;
    pdfStamper.Close();

    byte[] bt = memoryStream.GetBuffer(); //.ToArray()
    pdfReader.Close();

Download Project (full source code)

How can I solve this problem? Thank you!

È stato utile?

Soluzione

In Default.aspx.cs you do something relevant you left out in the code block of your question:

PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfReader, memoryStream, '\0');

PdfSignatureAppearance pdfSignatureAppearance = pdfStamper.SignatureAppearance;
//...
pdfSignatureAppearance.PreClose(exc);
//...

pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();

Whenever you call PdfSignatureAppearance.PreClose, you must also use PdfSignatureAppearance.Close, not PdfStamper.Close, cf. the method documentations:

/**
 * This is the first method to be called when using external signatures. The general sequence is:
 * preClose(), getDocumentBytes() and close().
 * <p>
 * If calling preClose() <B>dont't</B> call PdfStamper.close().
 * <p>
 * <CODE>exclusionSizes</CODE> must contain at least
 * the <CODE>PdfName.CONTENTS</CODE> key with the size that it will take in the
 * document. Note that due to the hex string coding this size should be
 * byte_size*2+2.
 * @param exclusionSizes a <CODE>HashMap</CODE> with names and sizes to be excluded in the signature
 * calculation. The key is a <CODE>PdfName</CODE> and the value an
 * <CODE>Integer</CODE>. At least the <CODE>PdfName.CONTENTS</CODE> must be present
 * @throws IOException on error
 * @throws DocumentException on error
 */
public void PreClose(Dictionary<PdfName, int> exclusionSizes) {

(from PdfSignatureAppearance.cs)

/**
 * Closes the document. No more content can be written after the
 * document is closed.
 * <p>
 * If closing a signed document with an external signature the closing must be done
 * in the <CODE>PdfSignatureAppearance</CODE> instance.
 * @throws DocumentException on error
 * @throws IOException on error
 */
public void Close() {

(from PdfStamper.cs)

The reason is that when you create a PdfStamper using CreateSignature(pdfReader, memoryStream, '\0'), the stamper itself does not write to the memory stream but instead to an internal ByteBuffer (this is required for the eventual signature creation and integration). No sooner than during PdfSignatureAppearance.Close the content of that ByteBuffer are written to the memory stream.

Furthermore I see you using

byte[] bt = memoryStream.GetBuffer();

Please don't! Unless you are sure that you are interpreting the buffer contents correctly (which may contain additional trash data), please use

byte[] bt = memoryStream.ToArray();

instead.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top