Jainish Jariwala
Jainish Jariwala

Reputation: 308

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

Upvotes: 0

Views: 2710

Answers (1)

Jainish Jariwala
Jainish Jariwala

Reputation: 308

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.

Upvotes: 2

Related Questions