2014-11-28 13 views
15

Nó đã đến với tôi để làm lại mã cũ có dấu hiệu tập tin PDF vào một mới, trong đó dấu hiệu MemoryStreams (mảng byte) đến và được gửi bởi các dịch vụ web. Đơn giản, phải không? Vâng, đó là ngày hôm qua. Hôm nay tôi không thể làm cho nó hoạt động được.Bắt PdfStamper để làm việc với MemoryStreams (C#, itextsharp)

Đây là mã cũ, trong đó sử dụng FileStreams và nó hoạt động:

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

Dưới đây là những gì tôi đã làm lại bản thân mình mà ném System.ObjectDisposedException: Không thể truy cập một Stream khép kín.

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

và nếu tôi nhận xét ra

st.Close(); 

nó tạo ra một tài liệu trống. Tôi đang làm gì sai?

+0

Hãy xem [câu trả lời này] (http://stackoverflow.com/a/25427872/1729265). – mkl

+0

Sự an toàn của chữ ký là ** không ** trách nhiệm của tôi. Trách nhiệm duy nhất của tôi là áp dụng chữ ký cho MemoryStream thay vì một FileStream. Và tôi đã đặt 'st.Writer.CloseStream = false;' trước 'st.Close();' Có ai giúp tôi ký một MemoryStream không? – ADSMarko

Trả lời

17

Không cụ thể để mã ký của bạn, nhưng khi làm việc với MemoryStreamPdfStamper, hãy làm theo mô hình chung này:

using (MemoryStream ms = new MemoryStream()) { 
    using (PdfStamper stamper = new PdfStamper(reader, ms, '\0', true)) { 
// do stuff  
    }  
    return ms.ToArray(); 
} 
  • MemoryStream thực hiện IDisposable, vì vậy bao gồm một tuyên bố using.
  • Tuyên bố PdfStamperusing xử lý việc xử lý đối tượng, vì vậy bạn không cần phải gọi Close() và không cần đặt thuộc tính CloseStream.
  • Đoạn mã của bạn đang trả lại mảng byte quá sớm, bên trong câu hỏi PdfStamperusing, vì vậy, MemoryStream của bạn thực sự là một no-op. Trả lại mảng byte ngoài của báo cáo kết quả PdfStamperusing, và bên tuyên bố MemoryStreamusing.
  • Thông thường, không cần phải đặt lại thuộc tính MemoryStreamPosition.
  • Bỏ qua công cụ xây dựng PdfStamper ở trên - đó là từ một số mã thử nghiệm mà tôi có để điền biểu mẫu và sử dụng bất kỳ phương thức/phương thức nào bạn cần thực hiện để ký.
+0

Cảm ơn bạn, @kuujinbo, bạn là một người tiết kiệm cuộc sống. Bây giờ làm thế nào để tôi thoát khỏi sự downvote đó, vì câu hỏi hoàn toàn hợp pháp? – ADSMarko

+0

@ADSMarko: Chỉ là một phong cách riêng của SO, vì vậy đừng để nó cho bạn. :) Vì lý do gì đó, ai đó không thích câu hỏi của bạn. Đối với những gì nó có giá trị, sẽ không có trả lời nếu tôi nghĩ rằng nó không phải là một câu hỏi hợp pháp, và thấy ** nhiều ** tồi tệ hơn mà không nhận được downvoted, vì vậy bạn có một upvote từ tôi. Nếu có thể, hãy xem xét thay đổi tiêu đề câu hỏi để phản ánh mối quan hệ trực tiếp 'PdfStamper' /' MemoryStream', vì đó là vấn đề cơ bản. – kuujinbo

+0

Sẽ làm, @kuujinbo. Cảm ơn – ADSMarko

Các vấn đề liên quan