0

Here is my chunk of code. It compiles fine and when I fire off the event I get the email, but I then get this error Email attachment ERROR on Adobe while opening(Acrobat could not open 'Att00002.pdf' because it is either not a supported file type or because the file has been damaged(for example, it was sent as an email attachment and wasnt correctly decoded.)

string agentName = "My Name";            
MemoryStream _output = new MemoryStream();
            PdfReader reader = new PdfReader("/pdf/Agent/Specialist_Certificate.pdf");
            using (PdfStamper stamper = new PdfStamper(reader, _output))
            {
                AcroFields fields = stamper.AcroFields;
            // set form fields
            fields.SetField("FIELD_AGENT_NAME", agentName);
            fields.SetField("FIELD_DATE", AvalonDate);

            // flatten form fields and close document
            stamper.FormFlattening = true;
            SendEmail(_output);
            DownloadAsPDF(_output);
            stamper.Close();
        }

private void SendEmail(MemoryStream ms)
{
    Attachment attach = new Attachment(ms, new System.Net.Mime.ContentType("application/pdf"));
    EmailHelper.SendEMail("myemail@myemail.com", "mjones@globusfamily.com", null, "", "Avalon Cert", "Hope this works", EmailHelper.EmailFormat.Html,attach);
}

EDITED *************************************

        using (MemoryStream _output = new MemoryStream())
        {
            using (PdfStamper stamper = new PdfStamper(reader, _output))
            {
                AcroFields fields = stamper.AcroFields;
                // set form fields
                fields.SetField("FIELD_AGENT_NAME", agentName);
                fields.SetField("FIELD_DATE", AvalonDate);

                // flatten form fields and close document
                stamper.FormFlattening = true;
            }
            SendEmail(_output);
        }
user1566783
  • 399
  • 1
  • 4
  • 18
  • Try closing the `PdfStamper` before calling `SendEmail`. You're probably attaching only part of the PDF bytestream because not everything is flushed to output yet. – rhens Oct 13 '15 at 17:57
  • When I change it to stamper.Close(); SendEmail(_output); I get this error when sending the email System.ObjectDisposedException: Cannot access a closed Stream – user1566783 Oct 13 '15 at 18:18

1 Answers1

3

You're calling stamper.close() inside the using (PdfStamper stamper = new PdfStamper(reader, _output)). The using will automatically close the stamper upon exiting it in addition to your manual close(), so technically the stamper is trying to be closed twice. Because of this it is also trying to close the MemoryStream more than once. That's where the exception is coming from.

I would use the technique located in the answer here for your MemoryStream and PdfStamper (modified and taken from: Getting PdfStamper to work with MemoryStreams (c#, itextsharp)):

using (MemoryStream _output = new MemoryStream()) {
  using (PdfStamper stamper = new PdfStamper(reader, _output)) {
// do stuff      
  }    
}
Community
  • 1
  • 1
Rick Burns
  • 1,538
  • 16
  • 20
  • 2
    I agree with this but I'd go even further and advocate for kuujinbo's full pattern which I also always use, and that's to return a byte array instead of a stream. If you need a stream later on, just wrap the byte array with a new one. Yes, there's a couple of extra CPU cycles in there but not much really. The problem with passing streams around is exactly what UncleRico is pointing to and that's that other people can mess with them by closing them or setting positions or whatever. – Chris Haas Oct 13 '15 at 20:58
  • Ok so where would I put my SendEmail(_output); chunk then? If I put it outside the using PdfStamper I get an error saying the stream is already closed. – user1566783 Oct 13 '15 at 22:42
  • @user1566783 I would advocate creating your stamped pdf first and closing it using the code above as a template. Then as a secondary process attach it to your e-mail using your `SendEmail()` method. Remember that in one case your MemoryStream is being used to write information, your attachment process is using that same MemoryStream to read from it (not really a good thing to do). – Rick Burns Oct 14 '15 at 12:37
  • So are you saying something like this? Since the using is closing the stamper, i send the email and then the using of the memorystream is closed as well. Or like Chris said above should I try putting it into a byte arrary and then sending it out in the attachment that way? – user1566783 Oct 14 '15 at 15:16
  • @user1566783. I like Chris' approach, however I've had success using the memorystreams as highlighted in my answer. So either would work. My own preference would be to use two memorystreams, one for the write of the new pdf and then another for the read of the resulting combined pdf for use in your e-mail. – Rick Burns Oct 14 '15 at 15:31
  • Ok I was able to get it up and working. Thanks guys for the help! – user1566783 Oct 14 '15 at 16:09