3

I can send an email and everything but I cannot create a valid Attachment() to put into my email. All examples I've found online assumes that it is somehow saved locally on my machine and links it via path but that is not the case. In my method, I create the file using Winnovative, and then I want to attach it to the e-mail and send it. No saving involved.

protected void SendEmail_BtnClick(object sender, EventArgs a) 
{
    if(IsValidEmail(EmailTextBox.Text)) 
    {
        try
        {
            MailMessage mailMessage = new MailMessage();
            mailMessage.To.Add(EmailTextBox.Text);
            mailMessage.From = new MailAddress("my email");
            mailMessage.Subject = " Your Order";

            string htmlstring = GenerateHTMLString();

            Document pdfDocument = GeneratePDFReport(htmlstring);
            //Attachment attachment = new Attachment("Receipt.pdf",pdfDocument);
            //mailMessage.Attachments.Add();

            SmtpClient smtpClient = new SmtpClient("smtp.gmail.com");
            //needs to change this password
            smtpClient.Credentials = new NetworkCredential("j@gmail.com","password"); //change password to password of email
            smtpClient.EnableSsl = true;
            try 
            {
                smtpClient.Send(mailMessage);
                EmailErrorMessage("Email Sent");
            }
            catch(Exception exc) 
            {
                EmailErrorMessage("Email could not be sent");
            }

        }
        catch (Exception ex)
        {

            EmailErrorMessage("Could not send the e-mail. Error: "+ex.Message);
        }
    }
    else 
    {
        EmailErrorMessage("Please input a valid email.");
    }
}

EDIT: This is my finished solution.

                MailMessage mailMessage = CreateMailMessage();
                SmtpClient smtpClient = CreateSMTPClient();
                string htmlstring = GenerateHTMLString();
                Document pdfDocument = GeneratePDFReport(htmlstring);

                // Save the document to a byte buffer
                byte[] pdfBytes;
                using (var ms = new MemoryStream())
                {
                    pdfDocument.Save(ms);
                    pdfBytes = ms.ToArray();
                }
                smtpClient.Send(mailMessage);
                EmailErrorMessage("Email Sent");



                // create the attachment
                Attachment attach;
                using (var ms = new MemoryStream(pdfBytes))
                {
                    attach = new Attachment(ms, "application.pdf");
                    mailMessage.Attachments.Add(attach);
                    try
                    {
                        smtpClient.Send(mailMessage);
                        EmailErrorMessage("Email Sent");
                    }
                    catch (Exception exc)
                    {
                        EmailErrorMessage("Could not send the e-mail properly. Error: " + exc.Message);
                    }
                } 

Result: The email sends, but the attachment is named application_pdf instead of application.pdf. Is there any way to fix this?

Soulzityr
  • 406
  • 1
  • 8
  • 26
  • 1
    `byte[] pdfBytes =pdfDocumnet.GetBytes()`//some how figure it out to read the byte array `Attachment att = new Attachment(new MemoryStream(pdfBytes),string name);` – MustangManiac May 30 '14 at 20:11
  • You need to save your `Document` to a memory stream, and then use that `MemoryStream` as the parameter to the [Attachment constructor](http://msdn.microsoft.com/en-us/library/ab7hb4y5(v=vs.110).aspx). – Jim Mischel May 30 '14 at 20:15
  • Among other things, your `MailMessage` and `SmtpClient` objects need to be in `using` blocks: `using (var mailMessage = new MailMessage()){using (var smtpClient = new SmtpClient("smtp.gmail.com")){...}}` – John Saunders May 31 '14 at 02:34

3 Answers3

8

I haven't used Winnovate's PDF, but a quick look at their documentation indicates that something like the following should work:

// Save the document to a byte buffer
byte[] pdfBytes;
using (var ms = new MemoryStream())
{
    pdfDocument.Save(ms);
    pdfBytes = ms.ToArray();
}

// create the attachment
Attachment attach;
using (var ms = new MemoryStream(pdfBytes))
{
    attach = new Attachment(ms, "application/pdf");
}

// and add it to the message
mailMessage.Attachments.Add(attach);

Edit after comments:

If might be that the stream has to remain open in order for the message to be sent. Perhaps use this to add the attachment and send the message:

Attachment attach;
var attachStream = new MemoryStream(pdfBytes);
try
{
    attachStream = new Attachment(ms, "application/pdf");
    mailMessage.Attachments.Add(attachStream);
    // do other stuff to message
    // ...
    // and then send it.
    smtpClient.Send(MailMessage)
}
finally
{
    attachStream.Close();
}
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • In my try{} catch(Exception exp) which is the inner one, I get an Inner Exception: Cannot Access A Closed Stream. I'm not sure what to do here. I looked into it and found this stackoverflow [link](http://stackoverflow.com/questions/10934585/memorystream-cannot-access-a-closed-stream) but I'm not quite sure I understand the issue. – Soulzityr May 31 '14 at 00:26
  • @LordHoneydew: If your code is the same as what I posted here, I don't see how you could be getting that exception. At what line is the exception thrown? Note that I'm creating two different memory streams here. The problem in your linked question is that the `StreamWriter` has closed the stream. You shouldn't have that problem here. – Jim Mischel May 31 '14 at 01:00
  • It's being thrown at smtpClient.Send(MailMessage). And yep my code is exactly the same here, just with my credentials deleted out. – Soulzityr May 31 '14 at 01:47
  • Hey sorry I took a break over the weekend. attachStream = new Attachment gives me the error that Atttachment cant be assigned to a memorystream. Also, i dont know why but I'm getting an error that MailMessage is not an applicable variable or member though it's highlighted blue – Soulzityr Jun 02 '14 at 20:44
  • going back to the original set up, how do i just keep the stream from closing? as that seems to be the issue. – Soulzityr Jun 02 '14 at 21:00
  • I added more to my original post. I kinda went back to using your original one. I was just trying to send it before the stream closes. Is this completely off the mark? – Soulzityr Jun 03 '14 at 02:29
  • could you look at my updated post? I have the email working now, just the attachment is weird – Soulzityr Jun 03 '14 at 22:29
1

You can use stream object to hold pdf string. You can use this stream object for attachment. Kindly explore attachment class at microsoft site.

http://msdn.microsoft.com/en-us/library/System.Net.Mail.Attachment(v=vs.110).aspx

1

byte[] pdfBytes = pdfDocumnet.GetBytes() //some how figure it out to read the byte array

You can read the bytes from the MemoryStream and send it to mail attachment as shown below

Attachment att = new Attachment(new MemoryStream(pdfBytes), name);

Mike Christensen
  • 88,082
  • 50
  • 208
  • 326
MustangManiac
  • 317
  • 2
  • 13