c# - 让 PdfStamper 与 MemoryStreams 一起工作(c#,itextsharp)

标签 c# pdf itext memorystream pdfstamper

我想到重新编写将 PDF 文件签名为新代码的旧代码,该代码对来自 Web 服务并发送的 MemoryStreams(字节数组)进行签名。简单吧?嗯,那是昨天。今天我就是无法让它工作。

这是旧代码,它使用 FileStreams 并且有效:

    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;
            }
        }
    }

下面是我自己重做的,它抛出 System.ObjectDisposedException:无法访问已关闭的流。

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

如果我注释掉

st.Close();

它创建一个空文档。我做错了什么?

最佳答案

不特定于您的签名代码,但在使用 MemoryStreamPdfStamper 时,请遵循以下一般模式:

using (MemoryStream ms = new MemoryStream()) {
  using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) {
// do stuff      
  }    
  return ms.ToArray();
}
  • MemoryStream 实现了 IDisposable,因此包含一个 using 语句。
  • PdfStamper using 语句负责处理对象,因此您不需要调用 Close(),也不需要不需要设置 CloseStream 属性。
  • 您的代码片段在 PdfStamper using 语句内太快返回字节数组,因此您的MemoryStream 实际上是一个空操作。返回 PdfStamper using 语句外部MemoryStream 内部 的字节数组使用语句。
  • 通常不需要重置 MemoryStream Position 属性。
  • 忽略上面的 PdfStamper 构造函数 - 它来 self 用于填写表单的一些测试代码,并使用您需要进行签名的任何构造函数/方法。

关于c# - 让 PdfStamper 与 MemoryStreams 一起工作(c#,itextsharp),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27188593/

相关文章:

c# - 使用 Silverlight 应用程序支持插件的最佳方式是什么?

java - 添加dss字典

java - 使用 java api 和 epass2003 token 的 pdf 数字签名

c# - 在 vbscript 中调用 C# dll

c# - 自增外键

perl - 如何使用 PDF 基元绘制实心和非实心圆?

c# - 使用 iTextSharp 和 PDFStamper 在 PDF 中使用不同的字体

java - 如何从 iText 获取书面 PDF 的 OutputStream

java - iText 无法将行保持在一起,第二行跨越多个页面,但不会与第一行保持一致

c# - 将 C# 哈希函数转换为 C++