让 PdfStamper 与 MemoryStreams 一起工作(c#、itextsharp) [英] Getting PdfStamper to work with MemoryStreams (c#, itextsharp)

查看:52
本文介绍了让 PdfStamper 与 MemoryStreams 一起工作(c#、itextsharp)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It came to me to rework old code which signs PDF files into new one, which signs MemoryStreams (byte arrays) that come and are sent by web services. Simple, right? Well, that was yesterday. Today I just can't get it to work.

这是旧代码,它使用 FileStreams 并且可以工作:

This is the old code, which uses FileStreams and it works:

    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), ''))
            {
                PdfSignatureAppearance sap = st.SignatureAppearance;
                sap.SetCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
                sap.Reason = reason;
                sap.Location = location;
                return destination;
            }
        }
    }

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

Below is what I've redone myself which throws System.ObjectDisposedException: Cannot access a closed Stream.

    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, ''))
            {
                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();

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

it creates an empty document. What am I doing wrong?

推荐答案

不特定于您的签名代码,但在使用 MemoryStreamPdfStamper 时,请遵循此通用模式:

Not specific to your signing code, but when working with MemoryStream and PdfStamper, follow this general pattern:

using (MemoryStream ms = new MemoryStream()) {
  using (PdfStamper stamper = new PdfStamper(reader, ms, '', true)) {
// do stuff      
  }    
  return ms.ToArray();
}

  • MemoryStream 实现了 IDisposable,因此包含一个 using 语句.
  • PdfStamper using 语句负责处理对象,因此您不需要调用 Close(),并且不要'不需要设置 CloseStream 属性.
  • 您的代码片段在 PdfStamper using 语句中返回字节数组 太快,因此您的 MemoryStream 实际上是一个空操作.返回PdfStamper using 语句的outsideMemoryStreaminside 字节数组using 语句.
  • 通常不需要重置 MemoryStream Position 属性.
  • 忽略上面的 PdfStamper 构造函数 - 它来自我用于填写表单的一些测试代码,并使用您需要进行签名的任何构造函数/方法.
    • MemoryStream implements IDisposable, so include a using statement.
    • The PdfStamper using statement takes care of disposing the object, so you don't need to call Close(), and don't need to set the CloseStream property.
    • Your code snippet is returning the byte array too soon, inside the PdfStamper using statement, so your MemoryStream is effectively a no-op. Return the byte array outside of the PdfStamper using statement, and inside the MemoryStream using statement.
    • Generally there's no need to reset the MemoryStream Position property.
    • Ignore the PdfStamper constructor above - it's from some test code I had for filling forms, and use whatever constructor/method you need to do your signing.
    • 这篇关于让 PdfStamper 与 MemoryStreams 一起工作(c#、itextsharp)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆