2016-12-02 5 views
1

Amazon SES C#SDKで添付ファイル付きの電子メールを送信するには、SendRawEmail関数を使用する必要があります非常に臭いです)。これを行うには、MIMEメッセージを手作業でコード化するか、System.Net.Mail.MailMessageオブジェクトをMemoryStreamに変換します。これはすべて正常に動作していますが、問題が発生しました。多くの掘り下げの後、私は問題を見つけてそれを複製することができました。そして、それはSMTPのドット・スタッフィングの副産物のようです。C#SDKを使用するとアマゾンSES、添付ファイル、ドットスタッフィングで2倍の問題が発生する

MailMessageが生のMIMEメッセージに変換されるとき、メッセージ本文のピリオドが生メッセージの行の先頭に折り返されると、ドットが詰まってしまう私が想定し)。しかし、電子メールが二重の期間を過ぎて来るので、SDKの内部またはSES側のどちらでも処理されていないようです。これは、出力されます生MIMEメッセージは、想定して、再度ドットスタッフィングを(見ることができます...

static void Main(string[] args) 
{ 
    var to = new List<string> { _toAddress }; 
    var subject = "TEST MESSAGE"; 
    var message = $"This is a carefully crafted HTML email message body such that you should see a single period right here ->. However, you'll see <strong>two periods</strong> in the email instead of one period like originally given in the code."; 

    var body = $"<br />Hello,<br /><br />{message}<br /><br />Sincerely,<br /><br />Your Tester"; 

    var result = SendEmail(to, subject, body, null, isHtml: true); 
    Console.WriteLine(result ? "Successfully sent message" : "Failed to send message"); 

    if (Debugger.IsAttached) 
    { 
     Console.WriteLine("Press any key to continue..."); 
     Console.ReadLine(); 
    } 
} 

private static bool SendEmail(List<string> to, string subject, string body, List<string> attachmentFilePaths = null, bool isHtml = false) 
{ 
    var message = new MailMessage 
    { 
     From = new MailAddress(_fromAddress), 
     Subject = subject, 
     Body = body, 
     IsBodyHtml = isHtml 
    }; 

    foreach (var address in to) 
    { 
     message.To.Add(address.Trim()); 
    } 

    if (attachmentFilePaths?.Any() == true) 
    { 
     foreach (var filePath in attachmentFilePaths) 
     { 
      message.Attachments.Add(new Attachment(filePath)); 
     } 
    } 

    try 
    { 
     var creds = new BasicAWSCredentials(_SESAccessKey, _SESSecretKey); 
     using (var client = new AmazonSimpleEmailServiceClient(creds, RegionEndpoint.USEast1)) 
     { 
      var request = new SendRawEmailRequest { RawMessage = new RawMessage { Data = ConvertMailMessageToMemoryStream(message) } }; 
      Console.WriteLine($"RawMessage.Data...\r\n\r\n{Encoding.ASCII.GetString(request.RawMessage.Data.ToArray())}"); 

      client.SendRawEmail(request); 
      return true; 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine($"AmazonSESHelper.SendEmail => Exception: {ex.Message}"); 
    } 

    return false; 
} 

// Have to do this reflection crap in order to send attachments to the SES API 
// From http://stackoverflow.com/questions/29532152/create-mime-mail-with-attachment-for-aws-ses-c-sharp/29533336#29533336 
private static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message) 
{ 
    var stream = new MemoryStream(); 
    var assembly = typeof(SmtpClient).Assembly; 
    var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter"); 

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

    var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic); 
    sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null); 

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

    return stream; 
} 

...次の例コンソールアプリケーションコードを介し

X-Sender: [email protected] 
X-Receiver: [email protected] 
MIME-Version: 1.0 
From: [email protected] 
To: [email protected] 
Date: 2 Dec 2016 11:45:36 -0500 
Subject: TEST MESSAGE 
Content-Type: text/html; charset=us-ascii 
Content-Transfer-Encoding: quoted-printable 

<br />Hello,<br /><br />This is a carefully crafted HTML email me= 
ssage body such that you should see a single period right here ->= 
.. However, you'll see <strong>two periods</strong> in the email i= 
nstead of one period like originally given in the code.<br /><br = 
/>Sincerely,<br /><br />Your Tester 

を複製することができ場合には)SMTPにつき適切だが、それは私がメールを受信したときに見られるように、送信後の未行われません...

enter image description here

私はこの仕事を得ることができます私は@jstedfast MimeKit(これは素晴らしい)を追加しますが、私のお気に入りのアプリケーションではないすべてのアプリケーションに別の依存関係を追加します。何かの前に、私は何かが欠けているかどうかを見るためにここに投げたかった。もしそうでなければ、SESがこれを問題として認識して修正するのを見てうれしいでしょう。それ以外の場合は、別のライブラリ依存関係か、SESから別のメールプロバイダにジャンプすることを決定する必要があります。

答えて

0

これはAWS側の問題ですが、すぐに(またはまったく)アドレッシングしないことになります。私は以来、我々のアプリにMimeKitに追加した

https://github.com/aws/aws-sdk-net/issues/501

は反射を経由してMimeに変換を交換する:ここで見ることができるように私はGitHubのレポに問題を投稿しました。新しいConvertMailMessageToMemoryStreamは次のとおりです。

private static MemoryStream ConvertMailMessageToMemoryStream(MailMessage message) 
{ 
    var stream = new MemoryStream(); 
    var mimeMessage = MimeMessage.CreateFromMailMessage(message); 
    mimeMessage.Prepare(EncodingConstraint.None); 
    mimeMessage.WriteTo(stream); 
    return stream; 
} 
関連する問題