使用Amazon-SES发送附件

我正在寻找一个有效的C#示例,用于向Amazon-SES发送附件。

在阅读Amazon-SES现在支持发送附件之后,我正在搜索C#示例,但无法找到它。

我认为使用AWS SDK for .NET和MimeKit是非常简单和干净的解决方案。 您可以通过SES API(而不是SMTP)发送带附件的电子邮件。

您可以直接将MimeMessage写入MemoryStream,然后将其与SES SendRawEmail一起使用:

using Amazon.SimpleEmail; using Amazon.SimpleEmail.Model; using Amazon; using Amazon.Runtime; using MimeKit; private static BodyBuilder GetMessageBody() { var body = new BodyBuilder() { HtmlBody = @"

Amazon SES Test body

", TextBody = "Amazon SES Test body", }; body.Attachments.Add(@"c:\attachment.txt"); return body; } private static MimeMessage GetMessage() { var message = new MimeMessage(); message.From.Add(new MailboxAddress("Foo Bar", "foo@bar.com")); message.To.Add(new MailboxAddress(string.Empty, "foobar@example.com")); message.Subject = "Amazon SES Test"; message.Body = GetMessageBody().ToMessageBody(); return message; } private static MemoryStream GetMessageStream() { var stream = new MemoryStream(); GetMessage().WriteTo(stream); return stream; } private void SendEmails() { var credentals = new BasicAWSCredentials("", ""); using (var client = new AmazonSimpleEmailServiceClient(credentals, RegionEndpoint.EUWest1)) { var sendRequest = new SendRawEmailRequest { RawMessage = new RawMessage(GetMessageStream()) }; try { var response = client.SendRawEmail(sendRequest); Console.WriteLine("The email was sent successfully."); } catch (Exception e) { Console.WriteLine("The email was not sent."); Console.WriteLine("Error message: " + e.Message); } } }
 public Boolean SendRawEmail(String from, String to, String cc, String Subject, String text, String html, String replyTo, string attachPath) { AlternateView plainView = AlternateView.CreateAlternateViewFromString(text, Encoding.UTF8, "text/plain"); AlternateView htmlView = AlternateView.CreateAlternateViewFromString(html, Encoding.UTF8, "text/html"); MailMessage mailMessage = new MailMessage(); mailMessage.From = new MailAddress(from); List toAddresses = to.Replace(", ", ",").Split(',').ToList(); foreach (String toAddress in toAddresses) { mailMessage.To.Add(new MailAddress(toAddress)); } List ccAddresses = cc.Replace(", ", ",").Split(',').Where(y => y != "").ToList(); foreach (String ccAddress in ccAddresses) { mailMessage.CC.Add(new MailAddress(ccAddress)); } mailMessage.Subject = Subject; mailMessage.SubjectEncoding = Encoding.UTF8; if (replyTo != null) { mailMessage.ReplyToList.Add(new MailAddress(replyTo)); } if (text != null) { mailMessage.AlternateViews.Add(plainView); } if (html != null) { mailMessage.AlternateViews.Add(htmlView); } if (attachPath.Trim() != "") { if (System.IO.File.Exists(attachPath)) { System.Net.Mail.Attachment objAttach = new System.Net.Mail.Attachment(attachPath); objAttach.ContentType = new ContentType("application/octet-stream"); System.Net.Mime.ContentDisposition disposition = objAttach.ContentDisposition; disposition.DispositionType = "attachment"; disposition.CreationDate = System.IO.File.GetCreationTime(attachPath); disposition.ModificationDate = System.IO.File.GetLastWriteTime(attachPath); disposition.ReadDate = System.IO.File.GetLastAccessTime(attachPath); mailMessage.Attachments.Add(objAttach); } } RawMessage rawMessage = new RawMessage(); using (MemoryStream memoryStream = ConvertMailMessageToMemoryStream(mailMessage)) { rawMessage.WithData(memoryStream); } SendRawEmailRequest request = new SendRawEmailRequest(); request.WithRawMessage(rawMessage); request.WithDestinations(toAddresses); request.WithSource(from); AmazonSimpleEmailService ses = AWSClientFactory.CreateAmazonSimpleEmailServiceClient(ConfigurationManager.AppSettings.Get("AccessKeyId"), ConfigurationManager.AppSettings.Get("SecretKeyId")); try { SendRawEmailResponse response = ses.SendRawEmail(request); SendRawEmailResult result = response.SendRawEmailResult; return true; } catch (AmazonSimpleEmailServiceException ex) { return false; } } public static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message) { Assembly assembly = typeof(SmtpClient).Assembly; Type mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); MemoryStream fileStream = new MemoryStream(); ConstructorInfo mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null); object mailWriter = mailWriterContructor.Invoke(new object[] { fileStream }); MethodInfo sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true }, null); MethodInfo closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic); closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null); return fileStream; } 

发现在这里

更新:.NET 4.5中的方法签名已更改,这破坏了上述内容: 在.NET 4.5 beta中将System.Net.Mail.MailMessage作为MemoryStream

您也可以设置IIS SMTP以通过SES进行中继。

您需要安装stunnel并进行设置

然后,您可以设置IIS SMTP 智能主机和其他一些选项,它将通过SES转发您的电子邮件。

来自上述链接要点的说明:

从亚马逊的文档中获取的说明并根据需要进行修改。

1.安装stunnel

  • stunnel的 下载页面下载
  • 使用默认选项运行安装程序,通过回答问题创建自签名证书
  • 在记事本中打开c:\program files (x86)\stunnel\stunnel.conf文件
  • 清除所有服务器配置(在Example SSL server mode services部分下,将没有client = yes行)
  • 创建一个新的客户端配置:

[SMTP-TLS-包装纸]
接受= 127.0.0.1:2525
客户=是
connect = email-smtp.us-east-1.amazonaws.com:465

  • 启动stunnel.exe并确保没有报告错误(您将获得一个小的系统托盘图标)
  • 如果成功,您可以选择安装为服务,方法是在命令行运行stunnel.exe -install (注意这会安装服务但不启动它,所以启动它)
  • 测试连接,在cmd行运行telnet localhost 2525 ,您应该看到来自Amazon服务器的SMTP响应(如果未安装telnet,请在服务器管理器/function/添加function中添加该function

2.配置IIS SMTP

  • 将智能主机设置为[127.0.0.1] (包括括号)
  • Outbound Connections部分中,将传出端口设置为2525 (如stunnel.conf文件)
  • 在“ 出站安全性”部分中,将身份validation信息设置为您的Amazon SMTP凭据,将其设置为基本身份validation( 注意:请勿检查TLS复选框)

这是一个使用MimeKit的非常简单的实现

 using Amazon; using Amazon.SimpleEmail; using Amazon.SimpleEmail.Model; using MimeKit; using System.IO; namespace SendEmailWithAttachments { class Program { static void Main(string[] args) { //Remember to enter your (AWSAccessKeyID, AWSSecretAccessKey) if not using and IAM User with credentials assigned to your instance and your RegionEndpoint using (var client = new AmazonSimpleEmailServiceClient("YourAWSAccessKeyID", "YourAWSSecretAccessKey", RegionEndpoint.USEast1)) using (var messageStream = new MemoryStream()) { var message = new MimeMessage(); var builder = new BodyBuilder() { TextBody = "Hello World" }; message.From.Add(new MailboxAddress("FROMADDRESS@TEST.COM")); message.To.Add(new MailboxAddress("TOADDRESS@TEST.COM")); message.Subject = "Hello World"; //I'm using the stream method, but you don't have to. using (FileStream stream = File.Open(@"Attachment1.pdf", FileMode.Open)) builder.Attachments.Add("Attachment1.pdf", stream); using (FileStream stream = File.Open(@"Attachment2.pdf", FileMode.Open)) builder.Attachments.Add("Attachment2.pdf", stream); message.Body = builder.ToMessageBody(); message.WriteTo(messageStream); var request = new SendRawEmailRequest() { RawMessage = new RawMessage() { Data = messageStream } }; client.SendRawEmail(request); } } } } 

我的存储库中有代码https://github.com/gianluis90/amazon-send-email

我不确定这是否是您正在寻找的,但它是我能够在这个主题上找到的唯一资源。 我也想更好地回答这个问题。

http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/

它说明了如何使用它,但至少对我来说是非常神秘的。

那里有更好的指南吗?

我也需要帮助,但到目前为止,我发现你需要发送一个多部分MIME消息,附件编码在base64中。

我认为您需要按照此链接上的说明操作。 亚马逊不允许您添加附件或其他更复杂的消息类型(iCalendar事件)。 基本上你需要通过字符串构建和操作来手工处理消息体。

目前,我在遗留系统上为iCalendar格式的电子邮件执行此操作。 这是一个痛苦的屁股,但如果你阅读RFC 2822,它会很清楚地告诉你格式是什么。 特别需要注意的事项:

  • Base64编码的数据
  • MIME类型
  • 确保您的多部分边界匹配(并且是唯一的)
  • 某些行之后的换行符数量(\ n)出现问题

祝你好运。 我不知道是否有一个开放的库可以在C#中为你做这类事情。 如果你能找到一个然后尝试使用它,因为处理RFC的复杂性应该有血压和脱发增加的医学通知。