将MailMessage转换为Stream会删除密件抄送

时间:2013-12-13 17:28:15

标签: c# mailmessage

使用此SO帖子(Convert MailMessage to Raw text),我们能够将MailMessage作为流获取。但是,Bcc被删除。 To和CC仍然有效,但不是Bcc。

为什么会将其删除,以及如何保留?

2 个答案:

答案 0 :(得分:2)

这是我的RawMessage()的VB.NET重组,其中包含标题中的BCC。基于其他人对原始SO链接的重复:http://colinmackay.co.uk/2011/11/10/sending-more-than-a-basic-email-with-amazon-ses

Public Class BuildRawMailHelper
    Private Const nonPublicInstance As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic

    Private Shared ReadOnly _mailWriterContructor As ConstructorInfo
    Private Shared ReadOnly _sendMethod As MethodInfo
    Private Shared ReadOnly _closeMethod As MethodInfo
    Private Shared ReadOnly _writeHeadersMethod As MethodInfo

    Shared Sub New()
        Dim systemAssembly As Assembly = GetType(SmtpClient).Assembly
        Dim mailWriterType As Type = systemAssembly.[GetType]("System.Net.Mail.MailWriter")

        _mailWriterContructor = mailWriterType.GetConstructor(nonPublicInstance, Nothing, {GetType(Stream)}, Nothing)

        _sendMethod = GetType(MailMessage).GetMethod("Send", nonPublicInstance)

        _closeMethod = mailWriterType.GetMethod("Close", nonPublicInstance)

        _writeHeadersMethod = mailWriterType.GetMethod("WriteHeaders", nonPublicInstance)
    End Sub

    Public Shared Function ConvertMailMessageToMemoryStream(message As MailMessage) As MemoryStream
        Using memoryStream As New MemoryStream()
            Dim mailWriter As Object = _mailWriterContructor.Invoke(New Object() {memoryStream})

            ' BCC is not output in headers by Send method, so we add it in manually
            If message.Bcc.Any Then
                Dim bccHeaders As New NameValueCollection()
                bccHeaders.Add("BCC", String.Join(", ", message.Bcc.Select(Function(x) x.ToString())))
                _writeHeadersMethod.Invoke(mailWriter, nonPublicInstance, Nothing, {bccHeaders, False}, Nothing)
            End If

            ' See http://stackoverflow.com/questions/9595440/getting-system-net-mail-mailmessage-as-a-memorystream-in-net-4-5-beta
            _sendMethod.Invoke(message, nonPublicInstance, Nothing, {mailWriter, True, True}, Nothing)

            _closeMethod.Invoke(mailWriter, nonPublicInstance, Nothing, {}, Nothing)

            Return memoryStream
        End Using
    End Function
End Class

答案 1 :(得分:1)

非常确定 BCC 字段永远不会随邮件一起发送。

BCC字段用于向收件人发送“Blind Carbon Copies”。来自WikiPedia

  

在通信的背景下,盲目抄送(缩写为Bcc :)允许消息的发件人隐藏从其他收件人输入Bcc:字段的人。

如果BCC字段中的收件人实际上包含在电子邮件的原始SMTP文本中,则无法强制执行此保证。

您在问题中链接到的方法很可能被SmtpClient用于准备要传输的消息。因此,它必须忽略BCC字段才能维持预期的行为。

要实际保留它,您必须手动将其插入输出文本中:

var email = new MailMessage();
using (var reader = new StreamReader(email.RawMessage())) 
using (var writer = new StringWriter()) {
    while(true) {
        var line = reader.ReadLine();
        if (line == null) break; // EOF

        if (line != "") { 
            // Header line
            writer.WriteLine(line);
            continue;
        }

        // End of headers, insert bcc, read body, then bail
        writer.WriteLine("Bcc: " + email.Bcc.ToString()); // or however you want to format it
        writer.WriteLine("");
        writer.Write(reader.ReadToEnd());
        break;
    }

    var messageText = writer.ToString();
    // Do something with message text which now has Bcc: header
}