+1 vote

How will you convert System.Net.Mail.MailMessage into eml file and get the byte[] out of it using Mail.dll?

by

1 Answer

0 votes

Using Mail.dll to parse eml data is easy:

IMail email = new MailBuilder().CreateFromEmlFile(@"c:\\file.eml");

Now for getting data from System.Net.Mail.MailMessage class:

You can configure the SmtpClient to send emails to the file system instead of the network. You can do this programmatically using the following code:

SmtpClient client = new SmtpClient("mysmtphost");
client.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
client.PickupDirectoryLocation = @"C:\somedirectory";
client.Send(message);

You can also set this up in your application configuration file like this:

 <configuration>
     <system.net>
         <mailSettings>
             <smtp deliveryMethod="SpecifiedPickupDirectory">
                 <specifiedPickupDirectory pickupDirectoryLocation="C:\somedirectory" />
             </smtp>
         </mailSettings>
     </system.net>
 </configuration>

After sending the email, you should see email files get added to the directory you specified. You can then have a separate process send out the email messages in batch mode.

You should be able to use the empty constructor instead of the one listed, as it won't be sending it anyway.

This is also another way, which requires reflection:

public static class MailMessageExtensions
{
    public static byte[] ToEml(this MailMessage message)
    {
        var assembly = typeof(SmtpClient).Assembly;
        var mailWriterType = assembly.GetType("System.Net.Mail.MailWriter");

        using (var memoryStream = new MemoryStream())
        {
            // Get reflection info for MailWriter contructor
            var mailWriterContructor = mailWriterType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(Stream) }, null);

            // Construct MailWriter object with our FileStream
            var mailWriter = mailWriterContructor.Invoke(new object[] { memoryStream });

            // Get reflection info for Send() method on MailMessage
            var sendMethod = typeof(MailMessage).GetMethod("Send", BindingFlags.Instance | BindingFlags.NonPublic);

            // Call method passing in MailWriter
            sendMethod.Invoke(message, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { mailWriter, true, true }, null);

            // Finally get reflection info for Close() method on our MailWriter
            var closeMethod = mailWriter.GetType().GetMethod("Close", BindingFlags.Instance | BindingFlags.NonPublic);

            // Call close method
            closeMethod.Invoke(mailWriter, BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { }, null);

            return memoryStream.ToArray();
        }
    }
}
by (301k points)
...