Rebex.Mail.MailMessage Load eml file

+1 vote
asked Feb 2, 2016 by Chris6 (280 points)

Hi,

I am processing a directory of emails sent via (System.Net.Mail.MailMessage) via he following directive:

 <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory" from="system@mlcs3.com">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\maildrop" />
      </smtp>
    </mailSettings>
  </system.net>

The files created in C:\maildrop are .eml files.

When I load these with rebex e.g.

Rebex.Mail.MailMessage mailMessage = new Rebex.Mail.MailMessage();
mailMessage.Load(@"C:\maildrop\3a992f12-3bb9-49a1-98e3-bfefaacd6897.eml");

I noticed if the email has a Bcc rebex does not pick it up, could you advise of a workaround / fix.

Thanks

Chris

Applies to: Rebex Secure Mail

1 Answer

0 votes
answered Feb 3, 2016 by Tomas Knopp (58,890 points)
selected Feb 3, 2016 by Chris6
 
Best answer

Hi,

the System MailMessage class when sending the email via IIS Pickup Directory actually does not include the BCC headers into the email. See this article for details. This is logical, as including Bcc headers into the email to be sent would reveal the BCC addresses to people receiving the email which is not desirable.

Instead the BCC recipients are stored in the "X-Receiver" headers that the IIS server cuts away before actually sending the email.

Parsing the "X-Receiver" headers can be easily done with Rebex Secure Mail. See my code below.

However, please note that apart of the BCC, the X-Receiver headers contains also the standard To and CC addresses. So based on your usage you have to differentiate these apart yourself.

MailMessage mail = new MailMessage();
mail.Load(@"C:\pickupDirectory\13a6b150-4cdc-4238-8beb-4f2966baac9f.eml");

MimeHeader[] xReceivers = mail.Headers.GetAllHeaders("X-Receiver");

List<MailAddress> receivers = new List<MailAddress>();
List<MailAddress> bccRecipients = new List<MailAddress>();

foreach (var xReceiver in xReceivers)
{
    var receiver = new MailAddress(xReceiver.Value.ToString());
    receivers.Add(receiver);
}
// X-Receiver headers contain all receivers (including To, CC and BCC).
// TODO: based on your usage, filter out the BCC addressees yourself!

// in this simple case let's suppose that To and CC only contains one address and that only one copy of each address occurs in To, CC and BCC
bool toIgnored = false, ccIgnored = false;
foreach (var receiver in receivers)
{
    // if X-Receiver is already set in To or CC, ignore the first occurence
    if (!toIgnored && mail.To[0].Address == receiver.Address)
    {
        toIgnored = true;
        continue;
    }
    if (!ccIgnored && mail.CC[0].Address == receiver.Address)
    {
        ccIgnored = true;
        continue;
    }
    bccRecipients.Add(receiver);
}

foreach (var bccRecipient in bccRecipients)
{
    Console.WriteLine("Found possible BCC recipient '{0}'.", bccRecipient);
    mail.Bcc.Add(bccRecipient);
}
commented Feb 3, 2016 by Chris6 (280 points)
Thanks, as I wanted a universal version I tweaked it as follows so it works with all scenarios. It might be worth adding this to the component since I suspect most people would not be aware the 'bcc' is not being read.


            MailMessage mail = new MailMessage();
            mail.Load(@"C:\maildrop\d4d653fb-090e-443b-9ab0-a9ef810db779.eml");

            MailAddress[] xReceiver = mail.Headers.GetAllHeaders("X-Receiver").Select(x => new MailAddress(x.Value.ToString())).ToArray();
            
            List<MailAddress> messageAddress = new List<MailAddress>();
            messageAddress.AddRange(mail.To);
            messageAddress.AddRange(mail.CC);

            MailAddress[] bccAddresses = (from Item1 in xReceiver
                         join Item2 in messageAddress on Item1.Address.ToLower() equals Item2.Address.ToLower() into ps
                         from p in ps.DefaultIfEmpty()
                         where p == null
                         select Item1).ToArray();

            mail.Bcc.Clear();
            mail.Bcc.AddRange(bccAddresses);

            // Send email
commented Feb 3, 2016 by Tomas Knopp (58,890 points)
Your code seems to be good. And thank you for your suggestion.

However, your use case seems to be quite rare and moreover, the X-Receiver header is not a MIME standard of any kind (it is just the IIS server that utilizes it together with System MailMessage), so unfortunatelly we cannot safely assume that we can take out BCC from the X-Receiver header every time. So this would have to be an option in the component to switch this on.

If there will be more interest in this feature we might consider it again in the future.
commented Feb 3, 2016 by Chris6 (280 points)
No worries, we only do it like this as it means the software can be responsive and is not waiting for the SMTP server to respond and when the SMTP server was down there was no easy retry mechanism.

Thanks

Chris
commented Feb 4, 2016 by Tomas Knopp (58,890 points)
Ok :) thanks
...