2

I'm working on a service that pulls multiple PDF files stored in a database as varbinary and merges them into a single file using Aspose - PDF. The merged file is then converted to a Memory Stream and then a blob and then sent to the webpage.

Here's my service:

    public MemoryStream GetPrintContent(List<ConfirmationRequestNoticeViewModel> models)
    {
        // Instantiate Pdf instance by calling its empty constructor
        Document pdf1 = new Document();

        byte[][] bytes = new byte[models.Count][];

        for (int i = 0; i < models.Count; i++)
        {
            ConfirmationRequestNoticeViewModel model = models[i];
            byte[] fileContent = _dataService.GetPrintContent(model.ConfirmationRequestId);
            bytes[i] = fileContent;

        }
        MemoryStream stream = new MemoryStream();
        List<Document> documents = GeneratePdfs(bytes, stream);
        stream = ConcatenatePdf(documents);
        return stream;
    }

    private MemoryStream ConcatenatePdf(List<Document> documents)
    {
        MemoryStream stream = new MemoryStream();
        Document mergedPdf = documents[0];
        for(int index = 1; index < documents.Count; index++)
        {
            for (int i = 0; i < documents[index].Pages.Count; i++)
            {
                mergedPdf.Pages.Add(documents[index].Pages[i + 1]);
            }
        }
        mergedPdf.Save(stream);
        return stream;
    }

    private List<Document> GeneratePdfs(byte[][] content, MemoryStream stream)
    {
        List<Document> documents = new List<Document>();
        Document pdf = new Document();
        foreach (byte[] fileContent in content)
        {
            using (MemoryStream fileStream = new MemoryStream(fileContent))
            {
                pdf = new Document(fileStream);
                pdf.Save(stream);
                documents.Add(pdf);
            }
        }
        return documents;
    }

Everything is working great except for the line mergedPdf.Save(stream); which returns the error Cannot access a closed stream.

I've been working on this and can't seem to understand why the Memory Stream has been closed. Has anyone else encountered this issue?

Edit:

I've found the issue listed here

Nathan Foss
  • 595
  • 1
  • 9
  • 34

2 Answers2

1

I couldn't solve the issue with closed MemoryStreams with the current implementation so I had to refactor completely.

Instead, I went with the PdfFileEditor.Concatenate() method explained in this forum post.

My implementation is as follows:

    public byte[] GetPrintContent(List<ConfirmationRequestNoticeViewModel> models)
    {
        PdfFileEditor pdfEditor = new PdfFileEditor();

        MemoryStream[] inputStreams = new MemoryStream[models.Count];
        MemoryStream fileStream = new MemoryStream(); ;


        using (MemoryStream outputStream = new MemoryStream())
        {
            for (int i = 0; i < models.Count; i++)
            {
                ConfirmationRequestNoticeViewModel model = models[i];
                byte[] fileContent = _dataService.GetPrintContent(model.ConfirmationRequestId);

                fileStream = new MemoryStream(fileContent);

                inputStreams[i] = fileStream;

            }
            bool success = pdfEditor.Concatenate(inputStreams, outputStream);
            byte[] data = outputStream.ToArray();
            fileStream.Dispose();
            return data;
        }

    }
Nathan Foss
  • 595
  • 1
  • 9
  • 34
0

For the closed memory Stream issue, you should remove the using(), as it disposes the stream while coming out of {}. It will work fine.

Jonathan
  • 1,955
  • 5
  • 30
  • 50