Asp.net PdfStamper.CreateSignature和空MemoryStream

Asp.net PdfStamper.CreateSignature和空MemoryStream,asp.net,.net-4.0,itextsharp,memorystream,pdfstamper,Asp.net,.net 4.0,Itextsharp,Memorystream,Pdfstamper,使用iTextSharp 5.3.4.0,我在使用PdfStamper和MemoryStream时遇到困难 内存流总是空的 PdfReader pdfReader = new PdfReader(Server.MapPath(@"Document.pdf")); MemoryStream memoryStream = new MemoryStream(); PdfStamper pdfStamper = PdfStamper.CreateSignature(pdfRe

使用iTextSharp 5.3.4.0,我在使用PdfStamper和MemoryStream时遇到困难

内存流总是空的

    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();


我怎样才能解决这个问题?谢谢大家!

在Default.aspx.cs中,您可以执行问题代码块中遗漏的相关操作:

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

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

pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();
无论何时调用
PdfSignatureAppearance.PreClose,
您还必须使用
PdfSignatureAppearance.Close,
not
PdfStamper.Close,
cf。方法文档:

/**
 * 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) {
(来自)

(来自)

原因是,当您使用
CreateSignature(pdfReader,memoryStream,'\0')创建
PdfStamper
时,
压模本身不会写入内存流,而是写入内部
字节缓冲
(这是最终签名创建和集成所必需的)。不早于
PdfSignatureAppearance期间。关闭
ByteBuffer
的内容将写入内存流

此外,我看到你使用

byte[] bt = memoryStream.GetBuffer();
请不要!除非您确定正确解释了缓冲区内容(可能包含其他垃圾数据),否则请使用

byte[] bt = memoryStream.ToArray();

相反。

在Default.aspx.cs中,您可以执行问题代码块中遗漏的相关操作:

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

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

pdfStamper.Writer.CloseStream = false;
pdfStamper.Close();
无论何时调用
PdfSignatureAppearance.PreClose,
您还必须使用
PdfSignatureAppearance.Close,
not
PdfStamper.Close,
cf。方法文档:

/**
 * 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) {
(来自)

(来自)

原因是,当您使用
CreateSignature(pdfReader,memoryStream,'\0')创建
PdfStamper
时,
压模本身不会写入内存流,而是写入内部
字节缓冲
(这是最终签名创建和集成所必需的)。不早于
PdfSignatureAppearance期间。关闭
ByteBuffer
的内容将写入内存流

此外,我看到你使用

byte[] bt = memoryStream.GetBuffer();
请不要!除非您确定正确解释了缓冲区内容(可能包含其他垃圾数据),否则请使用

byte[] bt = memoryStream.ToArray();

相反。

Hi@mkl,谢谢!但是发现了另一个困难…我应该遵循以下步骤:preClose()、getDocumentBytes()和close()。[1.]但getDocumentBytes()方法在PdfSignatureAppearance中不可用。[2.]close()方法需要参数PdfDictionary…我试图将一个用iText(JAVA)创建的示例复制到iTextSharp(.NET)。Bruno Lowagie在白皮书“PDF文档的数字签名”、“4.3.3使用在客户端创建的签名在服务器上签名”中介绍了该示例(第116页)。再次感谢1)getDocumentBytes似乎是一个遗留问题,使用rangeStream就是其中的一部分;2) 这本字典就是你注入外部签名的地方。你好@mkl,谢谢!但是发现了另一个困难…我应该遵循以下步骤:preClose()、getDocumentBytes()和close()。[1.]但getDocumentBytes()方法在PdfSignatureAppearance中不可用。[2.]close()方法需要参数PdfDictionary…我试图将一个用iText(JAVA)创建的示例复制到iTextSharp(.NET)。Bruno Lowagie在白皮书“PDF文档的数字签名”、“4.3.3使用在客户端创建的签名在服务器上签名”中介绍了该示例(第116页)。再次感谢1)getDocumentBytes似乎是一个遗留问题,使用rangeStream就是其中的一部分;2) 这本字典就是你注入外部签名的地方。