VS.NET 2010/2012 Users Click Here   

HOMECONTACT PRODUCTS DOWNLOADS PURCHASE TESTIMONIALS FORUMS COMPANY CONTACT
Home
Products
Downloads
Purchase
Licensing
Licensing FAQ
Software Updates
Support Forums
Testimonials
Feature Requests
Guarantee
About Us
Contact Us
Hosting Companies
Privacy Policy
   
Shopping Cart


Search
aspNetIMAP

RSS feed for aspNetIMAP Subscribe to category: aspNetIMAP

aspNetIMAP: Now supports the IDLE command.

by Dave 8. May 2012 08:23

aspNetIMAP Supports the IDLE Command

The IDLE command is a little different than the other IMAP commands. When the IDLE command is used, aspNetIMAP turns into a listening component. It listens for updates from the IMAP server. IMAP servers will usually send an Idle update response back, if messages are deleted, or new messages come in.  When a update is sent back, from the server to aspNetIMAP, the IdleResponse event is raised.  While aspNetIMAP is in Idle mode, no other commands can be sent against the server, until .IdleStop() is called.

The following steps are used to implement the Idle command (full code can be found below).

1)First we select a folder, in this example, the Inbox

            MailFolder inbox = imap.SelectInbox();

2)Then we wire up the event, that will get called every time an Idle update is sent to aspNetIMAP
            //wire up the idle event
            inbox.IdleResponse += new IdleResponseEventHandler(OnIdleResponse);

3) Start Idling
            inbox.Idle();

4)Now we wait. In this example, we are looping through a command promprt, until the user enters the word "stop". We could have just as easily implemented this in a windows form, in a button click event. And, subsequently, clicked another button to stop idling.
            string line = Console.ReadLine().ToLower();
            while (line != "stop")
            {

                line = Console.ReadLine().ToLower();
            }

5) Stop Idling
            inbox.IdleStop();


6)Get the last unseen message (usually the message that just came in, and caused the Idle event to be raised).
            //get the latest messges that just came in
            string unSeenSet = inbox.SearchClient.NotSeenSet();


The full example can be found below. In this example, we are creating a console.exe application. We could also convert this to windows form code just as easily.

[C#]

//in this example, use a console application, to wait for IDLE updates
private string gmailUsername = "test@gmail.com";
 private string gmailPassword = "secret";
 
 void IMAPGmail2IdleTest()
 {
     IMAP4 imap = OpenIMAPGmail();

     //get the inbox folder
     MailFolder inbox = imap.SelectInbox();

     //wire up the idle event
     inbox.IdleResponse += new IdleResponseEventHandler(OnIdleResponse);

     Console.WriteLine("starting to idle...");

     inbox.Idle();

     string line = Console.ReadLine().ToLower();
     while (line != "stop")
     {

         line = Console.ReadLine().ToLower();
     }

     Console.WriteLine("Stopping Idling...");
     inbox.IdleStop();

     //get the latest messges that just came in
     string unSeenSet = inbox.SearchClient.NotSeenSet();

     if ((unSeenSet != null) && (unSeenSet.Trim().Length > 0))
     {

         //convert to an array
         int[] unseenUnquieIds = inbox.MessageClient.ToUniqueIds(unSeenSet);

         int latestUniqueId = unseenUnquieIds[unseenUnquieIds.Length - 1];
         //download the latest uniqueId message
         MimeMessage message = inbox.FetchClient.Message(latestUniqueId, IndexType.UniqueId, true);

         if (message != null)
         {
             if (message.Subject != null)
             {
                 Console.WriteLine(message.Subject.Value);
             }
             else
             {
                 Console.WriteLine("No subject");
             }
         }

     }

     imap.Disconnect();
 }


 private IMAP4 OpenIMAPGmail()
 {
     IMAP4 imap = new IMAP4("imap.gmail.com");


     //create and load the ssl socket
     AdvancedIntellect.Ssl.SslSocket ssl = new AdvancedIntellect.Ssl.SslSocket();
     ssl.IgnoreInvalidCertificates = true;

     imap.LoadSslSocket(ssl);

     //logging on the ssl socket
     ssl.Logging = true;
     ssl.LogPath = "c:\\temp\\ssl.log";


     //rest of the IMAP properties
     imap.Port = 993;

     //any logging for troubleshooting
     imap.Logger = new IMAPLog();
     imap.Logger.Path = "c:\\temp\\imap.log";
     imap.Logger.Overwrite = true;

     imap.Connect();


     imap.Username = gmailUsername;
     imap.Password = gmailPassword;
     imap.Login();

     return imap;
 }
 void OnIdleResponse(object sender, IdleResponseEventArgs e)
 {
     //write out the response sent from the server
     string response = System.Text.Encoding.ASCII.GetString(e.Data, 0, e.DataCount);
     Console.WriteLine(response);
 }

[VB.NET]

'in this example, use a console application, to wait for IDLE updates

Private gmailUsername As String = "test@gmail.com"
Private gmailPassword As String = "secret"

Private Sub IMAPGmail2IdleTest()
	Dim imap As IMAP4 = OpenIMAPGmail()

	'get the inbox folder
	Dim inbox As MailFolder = imap.SelectInbox()

	'wire up the idle event
	AddHandler inbox.IdleResponse, AddressOf Me.OnIdleResponse

	Console.WriteLine("starting to idle...")

	inbox.Idle()

	Dim line As String = Console.ReadLine().ToLower()
	While line <> "stop"

		line = Console.ReadLine().ToLower()
	End While

	Console.WriteLine("Stopping Idling...")
	inbox.IdleStop()

	'get the latest messges that just came in
	Dim unSeenSet As String = inbox.SearchClient.NotSeenSet()

	If (unSeenSet IsNot Nothing) AndAlso (unSeenSet.Trim().Length > 0) Then

		'convert to an array
		Dim unseenUnquieIds As Integer() = inbox.MessageClient.ToUniqueIds(unSeenSet)

		Dim latestUniqueId As Integer = unseenUnquieIds(unseenUnquieIds.Length - 1)
		'download the latest uniqueId message
		Dim message As MimeMessage = inbox.FetchClient.Message(latestUniqueId, IndexType.UniqueId, True)

		If message IsNot Nothing Then
			If message.Subject IsNot Nothing Then
				Console.WriteLine(message.Subject.Value)
			Else
				Console.WriteLine("No subject")
			End If

		End If
	End If

	imap.Disconnect()
End Sub

Private Function OpenIMAPGmail() As IMAP4
	Dim imap As New IMAP4("imap.gmail.com")


	'create and load the ssl socket
	Dim ssl As New AdvancedIntellect.Ssl.SslSocket()
	ssl.IgnoreInvalidCertificates = True

	imap.LoadSslSocket(ssl)

	'logging on the ssl socket
	ssl.Logging = True
	ssl.LogPath = "c:\temp\ssl.log"


	'rest of the IMAP properties
	imap.Port = 993

	'any logging for troubleshooting
	imap.Logger = New IMAPLog()
	imap.Logger.Path = "c:\temp\imap.log"
	imap.Logger.Overwrite = True

	imap.Connect()


	imap.Username = gmailUsername
	imap.Password = gmailPassword
	imap.Login()

	Return imap
End Function

Private Sub OnIdleResponse(sender As Object, e As IdleResponseEventArgs)
	'write out the response sent from the server
	Dim response As String = System.Text.Encoding.ASCII.GetString(e.Data, 0, e.DataCount)
	Console.WriteLine(response)
End Sub

As always, if anyone has any questions, feel free to contact me using the Contact Us page found at this link.
Thanks!
Dave Wanta

Tags:

aspNetIMAP

aspNetIMAP and Message Count in Gmail

by Dave 9. March 2012 00:13

Message count in Gmail using aspNetIMAP

I recently had a customer pulling their hair out over this issue, so I thought I post something about it.

Sometimes when using aspNetIMAP (or any other IMAP client for that matter), the message count returned for a folder will not match what you actually see as a count in Gmail's web interface. The discrepancy is due to the conversational view. Gmail has an option to view messages as conversations. If you turn that option off (found under General | Settings in Gmail), you will get the true message count of messages in that folder.

 

aspNetIMAP: Fetching Headers, Size, Importance and Flags

by Dave 8. March 2011 00:58

I recently had a request about fetching different parts of a message from an IMAP server.  They wanted to get the following information as easily as possible:

Flags
Message Size
Importance
Attachment Names
Customer Headers
Recipients

The IMAP protocol does not support fetching this information in a single network call. However, all of these values can be fetched for a single message, using multiple calls. aspNetIMAP can do this for you in a nice, neat object called the MimeEnvelope object.  The MimeEnvelope object fetches all of the above data, and more.

Below is a code example that demonstrates using the MimeEnvelope object.

C#

	 IMAP4 imap = new IMAP4();
	 imap.Server = "192.168.1.4";
	 imap.Username = "dave@example.com";
	 imap.Password = "test";
	 imap.Login();
	 
	 MailFolder mf = imap.SelectInbox();       
	 
	 FetchClient fc = mf.FetchClient;
	 
	 MimeEnvelope[] menvelopes = fc.MimeEnvelope( "1:*", IndexType.Ordinal );
	 
	 
	 foreach( MimeEnvelope menvelope in menvelopes)
	 {
	 	//write out the attachment names
	 	Response.Write( "Attachment Count: " + menvelope.AttachmentNames.Length );
	 	if( menvelope.AttachmentNames.Length > 0 )
	 	{
	 		foreach( string attachmentName in menvelope.AttachmentNames )
	 		{
	 			Response.Write( attachmentName );
	 		}
	 	}
	 
	 	//write out the From, To, CC address information
	 	Response.Write( menvelope.FromName );
	 	Response.Write( menvelope.FromAddress );
	 	//To addresses
	 	foreach( string emailAddress in menvelope.To )
	 	{
	 		string name = menvelope.To[ emailAddress ];
	 		Response.Write( name );
	 		Response.Write( emailAddress );
	 	}
	 	//CC Addresses
	 	foreach( string emailAddress in menvelope.CC )
	 	{
	 		string name = menvelope.CC[ emailAddress ];
	 		Response.Write( name );
	 		Response.Write( emailAddress );
	 
	 	}
	 
	 	//write out other information
	 	Response.Write( "UniqueId: " + menvelope.UniqueId.ToString() );
	 	Response.Write( "Size: " + menvelope.Size.ToString() );
	 	Response.Write( "Flags: "+ menvelope.Flags.ToString() );
	 	Response.Write( "InternalDate: " + menvelope.InternalDate.ToString( "f",  DateTimeFormatInfo.InvariantInfo) );
	 	Response.Write( "Date: " + menvelope.Date.ToString( "f",  DateTimeFormatInfo.InvariantInfo) );
	 
	 	//subject
	 	Response.Write( menvelope.Subject );
	 	
	 	//priority
	 	Response.Write( "Priority: " + menvelope.Priority.ToString() );
	 
	 	Response.Write( "IsAnswered: " + menvelope.IsAnswered().ToString() );
	 	Response.Write( "IsDrafted: " + menvelope.IsDrafted().ToString() );
	 	Response.Write( "IsFlagged: " + menvelope.IsFlagged().ToString() );
	 	Response.Write( "IsRead: " + menvelope.IsRead().ToString() );
	 	Response.Write( "IsRecent: " + menvelope.IsRecent	().ToString() );
	 
	 	//retrieve a specific header named 'x-organization'
	 	Header h = menvelope.Headers[ "x-organization" ];
	 	if( ( h != null ) && ( h.Value != null ) )
	 	{
	 		Response.Write( h.Value );
	 	}
	 
	 	//write out the headers
	 	Response.Write( menvelope.HeaderString );
	 
	 	//write out the bodystructure of the message
	 	if( menvelope.BodyStructure != null )
	 	{
	 		Response.Write( menvelope.BodyStructure.ToString() );
	 	}
	 }
	 
	 
	 imap.Disconnect();
	 

VB.NET

	 Dim imap As New IMAP4()
	 imap.Server = "192.168.1.4"
	 imap.Username = "dave@example.com"
	 imap.Password = "test"
	 imap.Login()
	 
	 Dim mf As MailFolder = imap.SelectInbox()
	 
	 Dim fc As FetchClient = mf.FetchClient
	 
	 Dim menvelopes As MimeEnvelope() = fc.MimeEnvelope("1:*", IndexType.Ordinal)
	 
	 
	 Dim menvelope As MimeEnvelope
	 For Each menvelope In  menvelopes
	    'write out the attachment names
	    Response.Write(("Attachment Count: " + menvelope.AttachmentNames.Length))
	    If menvelope.AttachmentNames.Length > 0 Then
	       Dim attachmentName As String
	       For Each attachmentName In  menvelope.AttachmentNames
	          Response.Write(attachmentName)
	       Next attachmentName
	    End If
	    
	    'write out the From, To, CC address information
	    Response.Write(menvelope.FromName)
	    Response.Write(menvelope.FromAddress)
	    'To addresses
	    Dim emailAddress As String
	    For Each emailAddress In  menvelope.To
	       Dim name As String = menvelope.To(emailAddress)
	       Response.Write(name)
	       Response.Write(emailAddress)
	    Next emailAddress
	    'CC Addresses
	    Dim emailAddress As String
	    For Each emailAddress In  menvelope.CC
	       Dim name As String = menvelope.CC(emailAddress)
	       Response.Write(name)
	       Response.Write(emailAddress)
	    Next emailAddress 
	    
	    'write out other information
	    Response.Write(("UniqueId: " + menvelope.UniqueId.ToString()))
	    Response.Write(("Size: " + menvelope.Size.ToString()))
	    Response.Write(("Flags: " + menvelope.Flags.ToString()))
	    Response.Write(("InternalDate: " + menvelope.InternalDate.ToString("f", DateTimeFormatInfo.InvariantInfo)))
	    Response.Write(("Date: " + menvelope.Date.ToString("f", DateTimeFormatInfo.InvariantInfo)))
	    
	    'subject
	    Response.Write(menvelope.Subject)
	    
	    'priority
	    Response.Write(("Priority: " + menvelope.Priority.ToString()))
	    
	    Response.Write(("IsAnswered: " + menvelope.IsAnswered().ToString()))
	    Response.Write(("IsDrafted: " + menvelope.IsDrafted().ToString()))
	    Response.Write(("IsFlagged: " + menvelope.IsFlagged().ToString()))
	    Response.Write(("IsRead: " + menvelope.IsRead().ToString()))
	    Response.Write(("IsRecent: " + menvelope.IsRecent().ToString()))
	    
	    'retrieve a specific header named 'x-organization'
	    Dim h As Header = menvelope.Headers("x-organization")
	    If Not (h Is Nothing) And Not (h.Value Is Nothing) Then
	       Response.Write(h.Value)
	    End If
	    
	    'write out the headers
	    Response.Write(menvelope.HeaderString)
	    
	    'write out the bodystructure of the message
	    If Not (menvelope.BodyStructure Is Nothing) Then
	       Response.Write(menvelope.BodyStructure.ToString())
	    End If
	 Next menvelope
	 
	 
	 imap.Disconnect()

Downloading email using aspNetIMAP from Gmail

by Dave 2. March 2011 02:51


aspNetIMAP can easily fetch email from Gmail. To do this you must do the following:

a) Configure IMAP access in Gmail
b) Download the AdvancedIntellect.Ssl.dll from www.advancedintellect.com/download.aspx
c) Use aspNetIMAP over SSL at port 993 to connect.

Lets discuss this below.

Configure IMAP access in Gmail

Before you can access email, you must first configure IMAP in Gmail. To do this, log into Gmail, and click on the settings tab. You should see something similar to what is below. Basically, you want select "Enable IMAP".


Download the AdvancedIntellect.Ssl.dll
Once you have IMAP configured in Gmail, you need to download the AdvancedIntellect,Ssl.dll plugin to use with aspNetIMAP. You can download the dll from:
http://www.advancedintellect.com/download.aspx
Gmail only allows you to connect over IMAP using SSL. The  AdvancedIntellect,Ssl.dll allows you to do this.

Use aspNetIMAP over SSL at port 993 to connect.
Once you've downloaded the dll, you can integrate it into your project.

If you are using VS.NET, import the dll into your application, and set a reference to it.

If you are not using VS.NET, you should be able to just copy the dll to your /bin directory.

Once that is done, the following code example will get you started. This example simply downloads the message count from your inbox, and loops through the headers of the individual messages.


C#

IMAP4 imap = new IMAP4( "imap.gmail.com" );

//create and load the ssl socket
AdvancedIntellect.Ssl.SslSocket ssl = new AdvancedIntellect.Ssl.SslSocket();
imap.LoadSslSocket( ssl );

//logging on the ssl socket
ssl.Logging = true;
ssl.LogPath = "c:\\ssl.log";


//rest of the IMAP properties
imap.Port = 993;
imap.Username = "MyAccount@gmail.com";
imap.Password = "MyPassword";

//any logging for troubleshooting
imap.Logger = new IMAPLog();
imap.Logger.Path = "c:\\imap.log";
imap.Logger.Overwrite = true;

imap.Connect();

imap.Login();


//get the message count
MailFolder inbox = imap.SelectInbox();
int count = inbox.MessageCount;

//write it out
Response.Write( count.ToString() );

FetchClient fc = inbox.FetchClient;
//get the headers for each message (IMAP is a '1' based index. Start at '1'
for( int i=1;i<=count;i++)
{
	string headers = fc.Headers(i, IndexType.Ordinal );

	//do some work on the headers
	DoWork( headers );
}

imap.Disconnect();


VB.NET

Dim imap As New IMAP4("imap.gmail.com")

'create and load the ssl socket
Dim ssl As New AdvancedIntellect.Ssl.SslSocket()
imap.LoadSslSocket(ssl)

'logging on the ssl socket
ssl.Logging = True
ssl.LogPath = "c:\ssl.log"


'rest of the IMAP properties
imap.Port = 993

'any logging for troubleshooting
imap.Logger = New IMAPLog()
imap.Logger.Path = "c:\imap.log"
imap.Logger.Overwrite = True

imap.Connect()


imap.Username = "MyAccount@gmail.com"
imap.Password = "MyPassword"
imap.Login()


'get the message count
Dim inbox As MailFolder = imap.SelectInbox()
Dim count As Integer = inbox.MessageCount

'write it out
Response.Write(count.ToString())

Dim fc As FetchClient = inbox.FetchClient
'get the headers for each message (IMAP is a '1' based index. Start at '1'
Dim i As Integer
For i = 1 To count
   Dim headers As String = fc.Headers(i, IndexType.Ordinal)
   
   'do some work on the headers
   DoWork(headers)
Next i

imap.Disconnect()


As always, if anyone has any questions, feel free to contact me over at the Contact Us web page.


Thanks,
Dave Wanta

Fetching only Unread Messages

by Dave 17. February 2011 07:39

Today I had a request from Darren about how to read unread messages from an IMAP server. This is an excellent question. I should have added something like this to the help file.

To fetch unread messages, there are a number of classes we need to take advantage of in aspNetIMAP.

They are:
IMAP4 -- the object used to manage the connection to the IMAP server
MailFolder -- the object used to get access to the individual folder
SearchClient -- the object used to search for unread messages
FetchClient -- the object that actually fetches the content of the messages.

Without further delay, below is some sample code that can get you started for downloading unread messages.

//configure and connect to the IMAP server
IMAP4 imap = new IMAP4( "mail.blah.com", "dave@blah.com", "test" );
imap.Logger = new IMAPLog( "c:\\imap.log", false);
imap.Logger.Overwrite = true;
imap.Login();

//get the inbox
MailFolder inbox = imap.SelectInbox();

//get a list of message ids that are unread
SearchClient sc = inbox.SearchClient;

//return results as UniqueIds
sc.IndexType = IndexType.UniqueId;
string messageSet = inbox.SearchClient.NotSeenSet();

if( (messageSet == null ) || (messageSet.Length == 0 ) )
	return;

char[] commaArray = new Char[] {','};

//trim any ending commas
if( messageSet.EndsWith(",") )
	messageSet = messageSet.Trim( commaArray );

//split into individual message ids, so we can process 1 at a time.
string[] ids = messageSet.Split( commaArray);

//get an instance to the FetchClient
FetchClient fc = inbox.FetchClient;
foreach( string id in ids )
{
	if( id.Length == 0 )
		continue;

	int uid = int.Parse(id);

	//download the message
	MimeMessage msg = fc.Message( uid, IndexType.UniqueId, true );

	//process according to business rules
	ProcessMessage( msg );
}

imap.Disconnect();

To keep the code short, it is left up to the user to implement exception handling.

As always, if anyone has any questions, comments or requests, please let me know.

Thanks!
Dave Wanta

Parsing Cell Phone (mobile) generated emails

by Dave 9. November 2010 02:29

I have a number of customers who need to parse cell phone (mobile) generated emails. These emails come in configurations I never dreamed possible. Although they are technically Mime compliant, their individual parts can be ordered strangely, or have unique headers that normally aren't found in a standard message.

I was sent an email request from a developer (Thanks Cara!) about parsing a T-Mobile generated message. She needed to find and extract the text body part. If a text body part wasn't found, then the html body part was to be found, and converted to plain text. The other requirement was to find all of the images, and download (save) them to a directory.

Below is a code example is something I whipped up for her. She used it as a basis to get started with her application. Error checking has been left out, to keep the code short, workable, but complete.

As always, if anyone has any questions or comments, please let me know.

Thanks!
Dave Wanta

string path =  "t_mobile.eml";

MimeMessage m = MimeMessage.ParseFile( path );

MimePart textPart = m.TextMimePart;
if( textPart == null )
{
	//try and find it, by finding the first inline text part
	MimePartCollection inlineParts = m.InLineParts;
	if( ( inlineParts != null ) && ( inlineParts.Count >0 ) )
	{
		foreach( MimePart part in inlineParts )
		{
			if( (part.Name != null ) && ( part.Name.EndsWith(".txt") ) && ( part.ContentTypeString == "text/plain") )
			{
				//then we found our part
				textPart = part;
				break;
			}
		}
	}
}

string plainText = string.Empty;
if( textPart != null )
{
	plainText = textPart.DecodedText();
}

if( plainText.Length == 0 )
{
	//find the first html part.
	//get the plain text from the html part

	foreach( MimePart part in m.RetrieveAllParts() )
	{
		if( (part.ContentTypeString != null ) && ( part.ContentTypeString.ToLower() == "text/html") )
		{
			string html = part.DecodedText();
			//convert the Html to plain formatted text
			plainText = Utility.ConvertHtmlToText( html).Trim();
			break;
		}
	}
}

//extract all images, and save them to the temp directory
foreach( MimePart part in m.RetrieveAllParts() )
{
	if( part.IsImage() )
	{
		//normally, would need to check for images that already have the same filename
		//and rename accordingly
		//in this example, just save the images to the temp directory
		part.Save("c:\\temp\\");
	}
}

Using Advanced Intellect's Products in VS2010/2012

by Dave 9. November 2010 01:46

** NOTE: ALL OF OUR PRODUCTS RUN ON ALL VERSIONS OF .NET. **

The instructions below are for people using VS2010 and beyond.

                                                        --------------------------

As more and more people are upgrading to VS2010, and beyond, I am getting more of the following emails:

aspNetEmail (or any of our other products) doesn't work in later versions of Visual Studio. I usually get one of the following errors:

"aspNetEmail is not declared, it may be inaccessible due to its protection level."

Or

"The referenced assembly "…" could not be resolved because it has a dependency upon System.Web (or some other internal .NET namespace).  Please remove references to assemblies not in the targeted framework or consider retargeting your project"

Usually these exceptions occur when the developer is building a client side application.

Starting in VS2010, VS tries to be too smart for it's own good.  When you build a client application (console.exe, winform, etc…) VS limits the number of namespaces you need access too, because it thinks you shouldn't need them.

To change this behavior, what you need to do, is change the target framework from a subset of namespaces, to all of them.

To change this, in VS.NET Solution Explorer, Right-Click on  your project, an select Properties.
 
On the Application tab, set the Target Framework to be ".NET Framework XX". By default it is set to ".NET Framework XX Client Profile".  Press Ctrl-S for save, and you are done.

Below are 2 pictures that display changing the target framework.

As always, if anyone has any questions, feel free to contact me.

Thanks!
Dave Wanta

 

C# Screenshot:

 

VB.NET Screenshot (this option is found under the Compile tab. Then, click the "Advanced Compile Option" button.

 

 

 

Testimonial

Once again, thanks. Great control! "

Eric | Poulter Group

Read more testimonials
ListNanny aspNetDNS aspNetEmail aspNetPOP3 aspNetMX aspNetMIME aspNetPING aspNetTraceRoute aspNetIMAP aspNetMHT