Search code examples
c#asp.netimapmailkit

receive new unread mail every time in c# application from mailinbox


I want to achieve same functionality as like this one :

Notify C# Client, when SMTP Server receive a new Email

This is working fine. That method "NewMessageReceived" call successfully on every new mail receive.

But problem is that i can't fetch mail. I only got total count of INBOX in this method.

This code using the library : MailSystem.net

My Code as following :

        Imap4Client _imap;
        public static int cnt = 0;
        protected void Application_Start(object sender, EventArgs e)
        {
            var worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(StartIdleProcess);

            if (worker.IsBusy)
                worker.CancelAsync();

            worker.RunWorkerAsync();
        }
        private void StartIdleProcess(object sender, DoWorkEventArgs e)
        {
            if (_imap != null && _imap.IsConnected)
            {
                _imap.StopIdle();
                _imap.Disconnect();
            }

            _imap = new Imap4Client();
            _imap.ConnectSsl(ConfigurationManager.AppSettings["IncomingServerName"], Convert.ToInt32(ConfigurationManager.AppSettings["InPort"]));
            _imap.Login(ConfigurationManager.AppSettings["EmailAddress"], ConfigurationManager.AppSettings["Password"]);

            var inbox = _imap.SelectMailbox("INBOX");

            _imap.NewMessageReceived += new NewMessageReceivedEventHandler(NewMessageReceived);

            inbox.Subscribe();

            _imap.StartIdle();
        }

        public static void NewMessageReceived(object source, NewMessageReceivedEventArgs e)
        {
            cnt = e.MessageCount; //Inbox Count
            //here i want to fetch all unread mail from inbox
        }

I have found following solution to fetch unread mail:

http://mailsystem.codeplex.com/discussions/651129

It is saying me to use MailKit library. As i am already using MailSystem.net library , is there any way to achieve my requirement by using only one library ?

I am ready to use any other library also.

Please give me suggestion. Thanks


Solution

  • Yes, got it with single library : MailKit

    Look at following code of global.asax file:

            static CancellationTokenSource _done;
            ImapClient _imap;
            protected void Application_Start(object sender, EventArgs e)
            {
                var worker = new BackgroundWorker();
                worker.DoWork += new DoWorkEventHandler(StartIdleProcess);
    
                if (worker.IsBusy)
                    worker.CancelAsync();
    
                worker.RunWorkerAsync();
            }
    
            private void StartIdleProcess(object sender, DoWorkEventArgs e)
            {
                _imap = new ImapClient();
    
                _imap.Connect(ConfigurationManager.AppSettings["IncomingServerName"], Convert.ToInt32(ConfigurationManager.AppSettings["InPort"]), Convert.ToBoolean(ConfigurationManager.AppSettings["IncomingIsSSL"]));
                _imap.AuthenticationMechanisms.Remove("XOAUTH");
                _imap.Authenticate(ConfigurationManager.AppSettings["EmailAddress"], ConfigurationManager.AppSettings["Password"]);
    
                _imap.Inbox.Open(FolderAccess.ReadWrite);
                _imap.Inbox.MessagesArrived += Inbox_MessagesArrived;
                _done = new CancellationTokenSource();
                _imap.Idle(_done.Token);
            }
            static void Inbox_MessagesArrived(object sender, EventArgs e)
            {
                var folder = (ImapFolder)sender;
                //_done.Cancel(); // Stop idle process
                using (var client = new ImapClient())
                {
                    client.Connect(ConfigurationManager.AppSettings["IncomingServerName"], Convert.ToInt32(ConfigurationManager.AppSettings["InPort"]), Convert.ToBoolean(ConfigurationManager.AppSettings["IncomingIsSSL"]));
    
                    // disable OAuth2 authentication unless you are actually using an access_token
                    client.AuthenticationMechanisms.Remove("XOAUTH2");
    
                    client.Authenticate(ConfigurationManager.AppSettings["EmailAddress"], ConfigurationManager.AppSettings["Password"]);
    
                    int tmpcnt = 0;
                    client.Inbox.Open(FolderAccess.ReadWrite);
                    foreach (var uid in client.Inbox.Search(SearchQuery.NotSeen))
                    {
                        try
                        {
                            var message = client.Inbox.GetMessage(uid);
                            client.Inbox.SetFlags(uid, MessageFlags.Seen, true);
    
                            List<byte[]> listAttachment = new List<byte[]>();
    
                            if (message.Attachments.Count() > 0)
                            {
                                foreach (var objAttach in message.Attachments)
                                {
                                    using (MemoryStream ms = new MemoryStream())
                                    {
                                        ((MimeKit.ContentObject)(((MimeKit.MimePart)(objAttach)).ContentObject)).Stream.CopyTo(ms);
                                        byte[] objByte = ms.ToArray();
                                        listAttachment.Add(objByte);
                                    }
                                }
                            }
    
                            string subject = message.Subject;
                            string text = message.TextBody;
                            var hubContext = GlobalHost.ConnectionManager.GetHubContext<myHub>();
                            hubContext.Clients.All.modify("fromMail", text);
                            tmpcnt++;
                        }
                        catch (Exception)
                        { }
                    }
                    client.Disconnect(true);
                }
            }
    

    Now, i am able to receive new mail arrival event and also able to fetch unread mail in that event. Thanks MailKit.