web-dev-qa-db-ja.com

PdfStamperをMemoryStreams(c#、itextsharp)と連携させる

PDFファイルを新しいものに署名する古いコードを作り直し、Webサービスによって送信されて送信されるMemoryStream(バイト配列)に署名するようになりました。 。今日は機能しません。

これは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();

空のドキュメントを作成します。私は何を間違えていますか?

21
ADSMarko

署名コードに固有ではありませんが、MemoryStreamおよびPdfStamperを使用する場合は、次の一般的なパターンに従ってください。

_using (MemoryStream ms = new MemoryStream()) {
  using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) {
// do stuff      
  }    
  return ms.ToArray();
}
_
  • MemoryStreamIDisposableを実装するため、usingステートメントを含めます。
  • PdfStamperusingステートメントはオブジェクトの破棄を処理するため、Close()を呼び出す必要はなく、CloseStreamプロパティを設定する必要もありません。
  • コードスニペットは、PdfStamperusingステートメント内でバイト配列too soonを返しているため、MemoryStreamは実質的にノーオペレーションです。 PdfStamperusingステートメントのバイト配列外部、および内部MemoryStreamusingステートメントを返します。
  • 通常、MemoryStreamPositionプロパティをリセットする必要はありません。
  • 上記のPdfStamperコンストラクターは無視します-フォームに入力するために用意したテストコードからのもので、署名に必要なコンストラクター/メソッドを使用します。
21
kuujinbo