Создайте почту MIME с вложением для AWS SES c#

Я пытаюсь отправить почту AWS SES с вложением с помощью SDK. Я нашел рабочий код здесь:

он ссылается на MimeKitLite, но мы не можем ссылаться на него в .net framework 3.5. Есть ли обходной путь, который я могу написать в своем коде для отправки почты с использованием фреймворка 3.5? из-за некоторых зависимостей мы не можем обновить структуру нашего проекта.

Я пишу здесь свой рабочий код (фреймворк 4) для справки:

    protected void Page_Load(object sender, EventArgs e)
        {
            var message = (MimeMessage)MyMailMessage();
            var stream = new MemoryStream();
            message.WriteTo(stream);
            using (AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient("awsAccessKeyId", "awsSecretAccessKey", RegionEndpoint.USWest2))
            {
                var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage { Data = stream } };
                var response = client.SendRawEmail(sendRequest);
                Console.WriteLine(response.ToString());
            }
        }

   private static MimeKit.MimeMessage MyMailMessage()
        {
            var message = new MimeMessage();
            message.From.Add(new MailboxAddress("rahul", "[email protected]"));
            message.To.Add(new MailboxAddress("rahul", "[email protected]"));
            message.Subject = "Hello";
            var builder = new BodyBuilder();
            builder.HtmlBody = @"<p>Thank you for submitting your query/complaint.";
            //
            string attachement = System.Web.HttpContext.Current.Server.MapPath(Path.GetFileName("IntelOCL.log"));
            builder.LinkedResources.Add(attachement);
            message.Body = builder.ToMessageBody();
            return message;
        }

person Rahul Patel    schedule 09.04.2015    source источник
comment
FWIW, MimeKit теперь поддерживает .NET 3.5.   -  person jstedfast    schedule 23.11.2015


Ответы (1)


Вместо этого вы можете использовать класс .NET MailMessage. Проблема в том, что вы должны предоставить Amazon SES необработанное содержимое сообщения в потоке, а у этого класса нет прямого способа сделать это (на самом деле). Однако это можно сделать с помощью отражения:

private MemoryStream FromMailMessageToMemoryStream(MailMessage message)
{
   Assembly assembly = typeof(SmtpClient).Assembly;

   Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");

   MemoryStream stream = new MemoryStream();

   ConstructorInfo mailWriterContructor = 
      mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);
        object mailWriter = mailWriterContructor.Invoke(new object[] { stream });

   MethodInfo sendMethod = 
      typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);

   if (sendMethod.GetParameters().Length == 3)
   {
      sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null); // .NET 4.x
   }
   else
   {
      sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null); // .NET < 4.0 
   }

   MethodInfo closeMethod = 
      mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);
   closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);

    return stream;
}

С этой вспомогательной функцией ваш код будет теперь:

protected void Page_Load(object sender, EventArgs e)
    {
        var message = (MailMessage)MyMailMessage();
        var stream = FromMailMessageToMemoryStream(message);
        List<string> bccTo = new List<string>();
        bccTo.Add("[email protected]");
        using (AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient("awsAccessKeyId", "awsSecretAccessKey", RegionEndpoint.USWest2))
        {
            var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage { Data = stream } };
            var response = client.SendRawEmail(sendRequest);
            Console.WriteLine(response.MessageId);

            if (bccTo != null && bccTo.Count > 0)
            {
                sendRequest.Destinations = bccTo;
                response = client.SendRawEmail(sendRequest);
                Console.WriteLine(response.MessageId);
            }
        }
    }

private static MailMessage MyMailMessage()
    {
        var message = new MailMessage();
        message.From = new MailAddress("[email protected]", "rahul");
        message.To.Add("[email protected]");
        message.Subject = "Hello";
        message.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(@"<p>Thank you for submitting your query/complaint.", new ContentType("text/html")));
        //
        string attachmentname = "IntelOCL.log";
        Stream ms = new MemoryStream(File.ReadAllBytes(System.Web.HttpContext.Current.Server.MapPath(Path.GetFileName(attachmentname))));
        ContentType ct = new ContentType();
        ct.MediaType = "" // TODO
        Attachment attachment = new Attachment(ms, ct);
        attachment.Name = attachmentname;
        attachment.ContentDisposition.FileName = attachmentname;
        message.Attachments.Add(attachment);

        return message;
    }
person JPG    schedule 09.04.2015
comment
Привет JPG, спасибо за ваш код, он отлично работает, когда я сохраняю получателей в и копия, но когда я добавляю любого получателя в скрытую копию, этот получатель не получает почту, хотя и копия получает правильно. в коде нет исключений. Я использую песочницу AWS SES. Я делаю что-то неправильно? - person Rahul Patel; 28.04.2015
comment
@RahulPatel Я думаю, проблема в том, что объект .NET MIME не включает заголовки BCC. Для этого я предполагаю, что вы не можете использовать SendRawEmail, но вместо этого используйте SendEmail. - person JPG; 28.04.2015
comment
@RahulPatel Другим способом было бы отправить BCC отдельным письмом, см. отредактированный ответ. - person JPG; 29.04.2015
comment
Я получаю код состояния OK, вызов API выполнен успешно, но сообщения не принимаются, в чем может быть проблема? - person Nitin S; 15.10.2016
comment
@NitinSawant Это может быть проблема с IP-адресами AWS SES, помеченными как спам. Объект ответа содержит MessageId, на который можно ссылаться при обращении за поддержкой. - person JPG; 19.10.2016