让 PdfStamper 与 MemoryStreams 一起工作(c#、itextsharp) [英] Getting PdfStamper to work with 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?
推荐答案
不特定于您的签名代码,但在使用 MemoryStream
和 PdfStamper
时,请遵循此通用模式:
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
语句的outside 和MemoryStream
的inside 字节数组using
语句. - 通常不需要重置
MemoryStream
Position
属性. - 忽略上面的
PdfStamper
构造函数 - 它来自我用于填写表单的一些测试代码,并使用您需要进行签名的任何构造函数/方法. MemoryStream
implementsIDisposable
, so include ausing
statement.- The
PdfStamper
using
statement takes care of disposing the object, so you don't need to callClose()
, and don't need to set theCloseStream
property. - Your code snippet is returning the byte array too soon, inside the
PdfStamper
using
statement, so yourMemoryStream
is effectively a no-op. Return the byte array outside of thePdfStamper
using
statement, and inside theMemoryStream
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屋!