Search code examples
c#amazon-web-services.net-coreemail-attachmentsamazon-ses

How to Send an AWS Raw Email with pdf file attached to it in .Net Core?


Here's what I've done so far

public static async Task<bool> SendEmailWithAttachmentAsync(EmailObj emlData)
    {
        var replyToAddresses = new List<string>();
        replyToAddresses.Add("Email");

        try
        {
            var options = new CredentialProfileOptions
            {
                AccessKey = "1234",
                SecretKey = "5678"
            };

            var profile = new CredentialProfile("default", options);
            var sharedFile = new SharedCredentialsFile();
            sharedFile.RegisterProfile(profile);

            using (var client = new 
            AmazonSimpleEmailServiceClient(RegionEndpoint.APSoutheast2))
            {
                var bodyBuilder = new BodyBuilder();

                bodyBuilder.HtmlBody = "Hello World. Please view the attachment.";
                bodyBuilder.TextBody = "Hello World. Please view the attachment.";

                var mimeMessage = new MimeMessage();
                mimeMessage.From.Add(new MailboxAddress("Name", "Email"));
                mimeMessage.To.Add(new MailboxAddress("Recipient Name", "Email"));

                mimeMessage.Subject = "Hello World";
                
                //using (var messageStream = new MemoryStream())
                //{
                    MemoryStream messageStream = new MemoryStream();
                    
                    emlData.Report.ExportToPdf(messageStream);
                    messageStream.Seek(0, System.IO.SeekOrigin.Begin);
                bodyBuilder.Attachments.Add("File.pdf", messageStream, new 
                ContentType("application", "pdf"));
                mimeMessage.WriteTo(messageStream);
                
                var sendRequest = new SendRawEmailRequest {
                        Source = senderAddress,
                        Destinations = new List<string> { "Email" },
                        RawMessage = new RawMessage(messageStream)
                    };

                var response = await client.SendRawEmailAsync(sendRequest);

                if (response.MessageId != null)
                {
                    messageStream.Close();
                    messageStream.Flush();
                }

                    
                //}
                

                return true;
            }
        }
        catch (Exception err)
        {
            return false;
        }
    }

I've tried putting code into using(memoryStream){} but doesn't seem to be working. emlData.Report.ExportToPdf(messageStream); In here Report is XtraReport from DevExpress report, the code works as I've done the download part successfully but somehow sending an email doesn't work.

Any help would be appreciated, thank you. I've attached an image of what I got in my email.

enter image description here


Solution

  • I have followed the example in here and I was able to send an email with a PDF attachment with MimeKit using this code:

    public static void ReadPdfIntoMemoryStream(MemoryStream memoryStream)
    {
        byte[] fileContents = File.ReadAllBytes(filename);
        memoryStream.Write(fileContents, 0, fileContents.Length);
    }
    
    public static async Task<bool> SendEmailWithAttachmentAsync()
    {
        try
        {
            using (var client = new AmazonSimpleEmailServiceClient(RegionEndpoint.USEast1))
            {
                var bodyBuilder = new BodyBuilder();
    
                bodyBuilder.HtmlBody = "Hello World. Please view the attachment.";
                bodyBuilder.TextBody = "Hello World. Please view the attachment.";
    
                using (MemoryStream ms = new MemoryStream())
                {
                    ReadPdfIntoMemoryStream(ms);
                    ms.Seek(0, System.IO.SeekOrigin.Begin);
                    bodyBuilder.Attachments.Add("Test.pdf", ms, new ContentType("application", "pdf"));
                }
    
                var mimeMessage = new MimeMessage();
                mimeMessage.From.Add(new MailboxAddress("Name", senderAddress));
                mimeMessage.To.Add(new MailboxAddress("Recipient Name", destinationAddress));
                mimeMessage.Subject = "Hello World";
    
                mimeMessage.Body = bodyBuilder.ToMessageBody();
                using (var messageStream = new MemoryStream())
                {
                    await mimeMessage.WriteToAsync(messageStream);
                    var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage(messageStream) };
                    var response = await client.SendRawEmailAsync(sendRequest);
                    Console.WriteLine(response.HttpStatusCode);
                }
    
                return true;
            }
        }
        catch (Exception err)
        {
            Console.WriteLine(err.Message);
            return false;
        }
    }
    

    The ReadPdfIntoMemoryStream method emulates yours emlData.Report.ExportToPdf and loads a PDF into a memory stream. You can pass this memory stream directly to bodyBuilder attachments. Don't reuse this memory stream to send the raw message. Create a new one.