Posts Tagged ‘VB.NET’

Specify different port for FTP

Wednesday, October 19th, 2011

With Ftp.dll .NET FTP component establishing connection using default port is easy:

// C#

client.Connect("ftp.example.com");
' VB.NET

client.Connect("ftp.example.com")

If you need to specify different port just use overloaded version of Connect method:

// C#

client.Connect("ftp.example.com", 999);
// -or-
client.Connect("ftp.example.com", 999, false);
' VB.NET

client.Connect("ftp.example.com", 999)
' -or-
client.Connect("ftp.example.com", 999, False)

If you are using SSL:

// C#

client.ConnectSSL("ftp.example.com", 999);
// -or-
client.Connect("ftp.example.com", 999, true);
' VB.NET

client.ConnectSSL("ftp.example.com", 999)
' -or-
client.Connect("ftp.example.com", 999, True)

You can also specify the port range used in Active mode.

// C#

client.ActiveModePorts = new Range(1024, 1025);
' VB.NET

client.ActiveModePorts = New Range(1024, 1025)

You can strong>set the IP address announced to the FTP server in Active mode data transfer.
By default, the value of this property is IPAddress.None which means that the address of the network interface is used instead.

// C#

client.ActiveModeAddress = IPAddress.Parse("127.0.0.1");
' VB.NET

client.ActiveModeAddress = IPAddress.Parse("127.0.0.1")

How to access To, Cc, Bcc fields

Monday, October 10th, 2011

Recently some of the IMail interface address properties changed its types. The reason for this was to handle email groups nicely.

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

In those collections you can find two kinds of objectes:

  • MailBox class which represents single mailbox,
  • MailGroup class which represents group of email addresses.

Here’s the simplest code that prints only mailboxes:

// C#
using Lesnikowski.Mail.Headers;

private string PrintMailboxes(IEnumerable<MailAddress> addresses)
{
   List<string> parts = new List<string>();
   foreach (MailBox mailbox in addresses.OfType<MailBox>())
   {
       parts.Add(string.Format("{0} <{1}>",
           mailbox.Name,
           mailbox.Address));
   }
   return string.Join(", ", parts.ToArray());
}
' VB.NET
Imports Lesnikowski.Mail.Headers

Private Function PrintMailboxes(addresses As IEnumerable(Of MailAddress)) As String
  Dim parts As New List(Of String)()
  For Each mailbox As MailBox In addresses.OfType(Of MailBox)()
      parts.Add(String.Format("{0} <{1}>", _
		mailbox.Name, _
		mailbox.Address))
  Next
  Return String.Join(", ", parts.ToArray())
End Function

Here’s a slightly more complicated version that handles groups also:

// C#
using Lesnikowski.Mail.Headers;

private string PrintAllAddresses(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,
               PrintAllAddresses(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
Imports Lesnikowski.Mail.Headers

Private Function PrintAllAddresses(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)
         parts.Add(String.Format("{0} ({1})", _
            group.Name, _
            PrintAllAddresses(group.Addresses))) ' note the recursion
      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

Get supported authentication methods (IMAP, POP3, SMTP)

Thursday, October 6th, 2011

You can use SupportedAuthenticationMethodsto retrieve all authentication methods supported by the server:

// C#

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.example.org");
    client.UseBestLogin("user", "password");

    Console.WriteLine("Supported methods:");

    foreach (var method in client.SupportedAuthenticationMethods())
    {
        Console.WriteLine(method.Name);
    }

    Console.WriteLine("Supports CramMD5:");

    bool supportsCramMD5 = client.SupportedAuthenticationMethods()
        .Contains(ImapAuthenticationMethod.CramMD5);

    Console.WriteLine(supportsCramMD5);

    client.Close();
}
' VB.NET

Using client As New Imap()
    client.ConnectSSL("imap.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported methods:")

    For Each method As ImapAuthenticationMethod In client.SupportedAuthenticationMethods()
	    Console.WriteLine(method.Name)
    Next

    Console.WriteLine("Supports CramMD5:")

    Dim supportsCramMD5 As Boolean = client.SupportedAuthenticationMethods() _
        .Contains(ImapAuthenticationMethod.CramMD5)

    Console.WriteLine(supportsCramMD5)

    client.Close()
End Using

For example Gmail produces following output:

Supported method s:
IMAP4rev1
UNSELECT
IDLE
NAMESPACE
QUOTA
ID
XLIST
CHILDREN
X-GM-EXT-1
UIDPLUS
COMPRESS

Supports CramMD5:
False

We take great care for the API to look similar for all protocols (IMAP, POP3, SMTP).

Here’s the sample for POP3:

// C#

using (Pop3 client = new Pop3())
{
    client.ConnectSSL("pop3.example.org");
    client.UseBestLogin("user", "password");

    Console.WriteLine("Supported methods:");

    foreach (var method in client.SupportedAuthenticationMethods())
    {
        Console.WriteLine(method.Name);
    }

    Console.WriteLine("Supports CramMD5:");

    bool supportsCramMD5 = client.SupportedAuthenticationMethods()
        .Contains(Pop3AuthenticationMethod.CramMD5);

    Console.WriteLine(supportsCramMD5);

    client.Close();
}
' VB.NET

Using client As New Pop3()
    client.ConnectSSL("pop3.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported methods:")

    For Each method As Pop3AuthenticationMethod In client.SupportedAuthenticationMethods()
	    Console.WriteLine(method.Name)
    Next

    Console.WriteLine("Supports CramMD5:")

    Dim supportsCramMD5 As Boolean = client.SupportedAuthenticationMethods() _
        .Contains(Pop3AuthenticationMethod.CramMD5)

    Console.WriteLine(supportsCramMD5)

    client.Close()
End Using

Here’s the sample for SMTP:

// C#

using (Smtpclient = new Smtp())
{
    client.Connect("smtp.example.org");
    client.UseBestLogin("smtp", "password");

    Console.WriteLine("Supported methods:");

    foreach (var method in client.SupportedAuthenticationMethods())
    {
        Console.WriteLine(method.Name);
    }

    Console.WriteLine("Supports CramMD5:");

    bool supportsCramMD5 = client.SupportedAuthenticationMethods()
        .Contains(SmtpAuthenticationMethod.CramMD5);

    Console.WriteLine(supportsCramMD5);

    client.Close();
}
' VB.NET

Using client As New Smtp()
    client.Connect("smtp.example.org")
    client.UseBestLogin("user", "password")

    Console.WriteLine("Supported methods:")

    For Each method As SmtpAuthenticationMethod In client.SupportedAuthenticationMethods()
	    Console.WriteLine(method.Name)
    Next

    Console.WriteLine("Supports CramMD5:")

    Dim supportsCramMD5 As Boolean = client.SupportedAuthenticationMethods() _
        .Contains(SmtpAuthenticationMethod.CramMD5)

    Console.WriteLine(supportsCramMD5)

    client.Close()
End Using

Remove attachments from email

Thursday, October 6th, 2011

First I want to make one thing clear, neither POP3 nor IMAP protocols does not provide any way to remove attachments from existing emails.
This is because email stored on the server is immutable.
With IMAP protocol you can copy it to different folder, you can apply some flags (SEEN) to it, but you can’t change any part of the message.

The second important thing is that attachments are not stored separately from the message text and headers – they are embedded inside the email.

Nevertheless Mail.dll provides an easy way to create new email without the attachments from existing email message.

// C# 

IMail original = new MailBuilder().CreateFromEml(eml);
IMail email = original.RemoveAttachments().Create();
' VB.NET

Dim original As IMail = New MailBuilder().CreateFromEml(eml)
Dim email As IMail = original.RemoveAttachments().Create()

RemoveAttachments method also has an overloaded version that allows to remove only visual (content-disposition: inline) or/and non-visual (content-disposition: attachment) attachments:

// C# 

MailBuilder RemoveAttachments();

MailBuilder RemoveAttachments(
    bool removeVisuals,
    bool removeNonVisuals);
' VB.NET

Function RemoveAttachments() As MailBuilder

Function RemoveAttachments( _
    removeVisuals As Boolean, _
    removeNonVisuals As Boolean) As MailBuilder

The following example illustrates the full process of downloading email from IMAP server,
creating new email, with the same information, but without attachments, and finally uploading it, and removing the original message:

// C# 

using(Imap imap = new Imap())
{
    imap.ConnectSSL("imap.example.org");
    imap.UseBestLogin("user", "password");
    imap.SelectInbox();

    foreach (long uid in imap.GetAll())
    {
        string eml = imap.GetMessageByUID(uid);
        IMail original = new MailBuilder().CreateFromEml(eml);
        if (original.Attachments.Count > 0)
        {
            IMail email = original.RemoveAttachments().Create();

            imap.UploadMessage("Inbox", email);

            imap.DeleteMessageByUID(uid);
        }
    }
    imap.Close();
}
' VB.NET

Using imap As New Imap()
   imap.ConnectSSL("imap.example.org")
   imap.UseBestLogin("user", "password")
   imap.SelectInbox()

   For Each uid As Long In imap.GetAll()
      Dim eml As String = imap.GetMessageByUID(uid)
      Dim original As IMail = New MailBuilder().CreateFromEml(eml)
      If original.Attachments.Count > 0 Then
         Dim email As IMail = original.RemoveAttachments().Create()

         imap.UploadMessage("Inbox", email)

         imap.DeleteMessageByUID(uid)
      End If
   Next
   imap.Close()
End Using

Create Gmail url-ID via IMAP

Tuesday, August 30th, 2011

This is Gmail link that points to certain conversation:

https://mail.google.com/mail/u/0/#inbox/13216515baefe747

“13216515baefe747″ is the Gmail thread-ID in hex.

Here’s the code that:

  1. Selects “All Mail” folder
  2. Gets the newest message UID
  3. Obtains Gmail thread ID for this message (X-GM-THRID)
  4. Converts it to hex
  5. Creates the url that point to the Gmail conversation
// C# version

using (Imap client = new Imap())
{
    client.ConnectSSL("imap.gmail.com");
    client.Login("pat@gmail.com", "password");

    // select "All Mail" folder
    List&lt;FolderInfo&gt; allFolders = client.GetFolders();
    FolderInfo allMail = new CommonFolders(allFolders).AllMail;
    client.Select(allMail);

    // get IMAP uid of the newest message
    long lastUid = client.GetAll().Last();

    // get message info
    MessageInfo info = client.GetMessageInfoByUID(lastUid);

    // extract Gmail thread ID
    Int64 threadId = Int64.Parse(info.Envelope.GmailThreadId);
    string threadIdAsHex = threadId.ToString"X");

    // create url
    string url = string.Format(
        "https://mail.google.com/mail/u/0/#inbox/{0}",
        threadIdAsHex);

    Console.WriteLine(url);

    client.Close();
}
' VB.NET version

Using client As New Imap()
	client.ConnectSSL("imap.gmail.com")
	client.Login("pat@gmail.com", "password")

	' select "All Mail" folder
	Dim allFolders As List(Of FolderInfo) = client.GetFolders()
	Dim allMail As FolderInfo = New CommonFolders(allFolders).AllMail
	client.[Select](allMail)

	' get IMAP uid of the newest message
	Dim lastUid As Long = client.GetAll().Last()

	' get message info
	Dim info As MessageInfo = client.GetMessageInfoByUID(lastUid)

	' extract Gmail thread ID
	Dim threadId As Int64 = Int64.Parse(info.Envelope.GmailThreadId)
	Dim threadIdAsHex As String = threadId.ToString("X")

	' create url
	Dim url As String = String.Format( _
		"https://mail.google.com/mail/u/0/#inbox/{0}", _
		threadIdAsHex)

	Console.WriteLine(url)

	client.Close()
End Using

Here you can find some more information about how to search by X-GM-THRID and all other Gmail IMAP extensions.