Получение PdfStamper для работы с MemoryStreams (С#, itextsharp)
Мне пришло в голову переработать старый код, который подписывает PDF файлы на новый, который подписывает 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();
он создает пустой документ. Что я делаю неправильно?
Ответы
Ответ 1
Не определен для вашего кода подписи, но при работе с MemoryStream
и PdfStamper
следуйте этому общему шаблону:
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
using
.
- Как правило, нет необходимости в reset свойстве
MemoryStream
Position
.
- Игнорировать конструктор
PdfStamper
выше - это из некоторого тестового кода, который у меня был для заполнения форм, и использовать любой конструктор/метод, который вам нужен для подписания.