Using this SO post (Convert MailMessage to Raw text), we were able to get the MailMessage as a stream. However, the Bcc is removed. Both To and CC still work, but not Bcc.
Why would it be removed, and how can it be kept in?
Using this SO post (Convert MailMessage to Raw text), we were able to get the MailMessage as a stream. However, the Bcc is removed. Both To and CC still work, but not Bcc.
Why would it be removed, and how can it be kept in?
Pretty sure the BCC field never gets sent along with the message.
The BCC field is used to send "Blind Carbon Copies" to recipients. From WikiPedia:
In the context of correspondence, blind carbon copy (abbreviated Bcc:) allows the sender of a message to conceal the person entered in the Bcc: field from the other recipients.
If the recipients in the BCC field were actually contained in the raw SMTP text of the email, then this guarantee could not be enforced.
The method you linked to in your question is more than likely used by SmtpClient
to prepare the message for transmission. As such, it would have to ignore the BCC field in order to maintain the expected behavior.
To actually keep it in, you would have to manually insert it into the output text:
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
}
Here's my VB.NET rehash of RawMessage() which includes BCC in the headers. Based on someone else's rehash of the original SO link: 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