How to access To, Cc, Bcc fields

IMail To, Cc, Bcc and ReplyTo properties are of IList<MailAddress> type (that is IList Of MailAddress in VB.NET).

The reason for this, is to handle not only regular mailboxes but also email groups.

In those collections you can find two kinds of objects:

  • MailBox – which represents single mailbox (e.g. “John” <john@example.org>),
  • MailGroup – which represents group of email addresses (e.g. Accounting: <pat@example.org>, “John” <john@example.com>; ).

Limilabs.Mail.Headers namespace

First remember that you need to import Limilabs.Mail.Headers namespace:

// C#

using Limilabs.Mail.Headers;
' VB.NET

Imports Limilabs.Mail.Headers

GetMailboxes method

The simplest way to access actual email addresses is to use overloaded GetMailboxes method.

This method returns all mailboxes represented by an email address: in case of MailGroup it returns all mailboxes represented by the group and all child groups, in case of MailBox returns a list containing a single mailbox:

// C#

IMail mail = ...;
foreach (MailAddress address in mail.To)
{
    foreach (MailBox mailbox in address.GetMailboxes())
    {
        Console.WriteLine("{0} <{1}>", mailbox.Name, mailbox.Address);
    }    
}
' VB.NET

Dim mail As IMail = ...
For Each address As MailAddress In mail.To
    For Each mailbox As MailBox In address.GetMailboxes()
        Console.WriteLine("{0} <{1}>", mailbox.Name, mailbox.Address)
    Next
Next

You can also use LINQ:

// C#

IMail mail = ...;
var mailboxes = email.To.SelectMany(address => address.GetMailboxes());  

Ignore groups

If for some reason you want to ignore MailGroups you can use following code:

// C#

IMail mail = ...;
foreach (MailBox mailbox in mail.To.OfType<MailBox>())
{
    Console.WriteLine("{0} <{1}>", mailbox.Name, mailbox.Address);
}
' VB.NET

Dim mail As IMail = ...
For Each mailbox As MailBox In mail.[To].OfType(Of MailBox)()
	Console.WriteLine("{0} <{1}>", mailbox.Name, mailbox.Address)
Next

Extract all mailboxes

Here are sample functions that print all mailboxes (including those in groups) to string:

// C#

private string PrintMailboxes(IEnumerable<MailAddress> addresses)
{
    List<MailBox> mailboxes = new List<MailBox>();
    foreach (MailAddress address in addresses)
    {
        mailboxes.AddRange(address.GetMailboxes());
    }
    return string.Join(", ", mailboxes.ConvertAll(
        x => string.Format("'{0}' <{1}>", x.Name, x.Address)).ToArray());
}
' VB.NET
Imports Limilabs.Mail.Headers

Private Function PrintMailboxes(addresses As IEnumerable(Of MailAddress)) As String
    Dim mailboxes As New List(Of MailBox)()
    For Each address As MailAddress In addresses
    	mailboxes.AddRange(address.GetMailboxes())
    Next
    Return String.Join(", ", mailboxes.ConvertAll( _
        Function(x) String.Format("'{0}' <{1}>", x.Name, x.Address)).ToArray())
End Function

Handle groups and mailboxes

If you need to handle email groups differently than regular mailboxes, you need to use is operator:

// C#

private string PrintAddresses(IEnumerable<MailAddress> addresses)
{
    List<string> parts = new List<string>();
    foreach (MailAddress address in addresses)
    {
        if (address is MailGroup)
        {
            MailGroup group = (MailGroup)address;
            parts.Add(string.Format("'{0}': ({1})",
                group.Name,
                PrintAddresses(group.Addresses))); // recursion
        }
        if (address is MailBox)
        {
            MailBox mailbox = (MailBox)address;
            parts.Add(string.Format("'{0}' <{1}>",
                mailbox.Name,
                mailbox.Address));
        }
    }
    return string.Join(", ", parts.ToArray());
}
' VB.NET

Private Function PrintAddresses(addresses As IEnumerable(Of MailAddress)) As String
    Dim parts As New List(Of String)()
    For Each address As MailAddress In addresses
        If TypeOf address Is MailGroup Then
            Dim group As MailGroup = DirectCast(address, MailGroup) ' recursion
            parts.Add(String.Format("'{0}': ({1})", _
                group.Name, _
                PrintAddresses(group.Addresses)))
        End If
        If TypeOf address Is MailBox Then
            Dim mailbox As MailBox = DirectCast(address, MailBox)
            parts.Add(String.Format("'{0}' <{1}>", _
                mailbox.Name, _
                mailbox.Address))
        End If
    Next
    Return String.Join(", ", parts.ToArray())
End Function

Check if address list contains email

Finally here’s a helper function, you can use when, you want to know, if specified email address is in the recipients list:

// C#

if (ContainsEmail(email.To, "pat@example.com"))
{
    // ...
}

private static bool ContainsEmail(IEnumerable<MailAddress> list, string email)
{
    foreach (MailAddress address in list)
    {
        if (address.GetMailboxes().ConvertAll(x => x.Address).Contains(email))
            return true;
    }
    return false;
}

// Linq version:
private static bool ContainsEmail(IEnumerable<MailAddress> list, string email)
{
    return list.Any(address => address.GetMailboxes().ConvertAll(
        x => x.Address).Contains(email));
}
' VB.NET

If ContainsEmail(email.[To], "pat@example.com") Then
    ' ...
End If

Private Shared Function ContainsEmail(list As IEnumerable(Of MailAddress), email As String) As Boolean
    For Each address As MailAddress In list
        If address.GetMailboxes().ConvertAll(Function(x) x.Address).Contains(email) Then
            Return True
        End If
    Next
    Return False
End Function

' Linq version:
Private Shared Function ContainsEmail(list As IEnumerable(Of MailAddress), email As String) As Boolean
    Return list.Any(Function(address) address.GetMailboxes().ConvertAll( _
        Function(x) x.Address).Contains(email))
End Function

Tags: , ,

2 Responses to “How to access To, Cc, Bcc fields”

  1. Get common email fields (Subject, Text) with POP3 | Blog | Limilabs Says:

    […] a bit tricky as they can contain address groups. You can learn more about how to work with them in how to access To, Cc, Bcc fields […]

  2. Get common email fields (Subject, Text) with IMAP | Blog | Limilabs Says:

    […] a bit tricky as they can contain address groups. You can learn more about how to work with them in how to access To, Cc, Bcc fields […]

Questions?

Consider using our Q&A forum for asking any questions.