This project is read-only.

Pagination of messages

Topics: Help requests
Sep 28, 2014 at 10:01 PM
Hi Pavel,

My complements for nice work.

How do I get messages in chunks, like 25 at each search.

I mean the first 25 is easy by setting "count" to 25, but second call ... how to get messages 26-50 ??

Best regards, Per
Oct 3, 2014 at 9:34 PM
Hi Per,

in the current version, pagination is not supported, however, there is a workaround for this. I will make a small sample and publish it here tomorrow.


Nov 25, 2014 at 2:34 AM
Hi Pavel,

Do you have any idea when this workaround sample will be available?

And if it will take a few more months, can you give me something on how to think so I can try myself?

BR, Per
Dec 11, 2014 at 6:43 AM

I'd like to weight in here. This is a dealbreaking issue. I'm getting out of memory exception because i need to browse a giant folder in company inbox because there's too much messages. Buffering and paging the messages is a must have for an imap library.
Dec 11, 2014 at 9:22 AM
Edited Dec 11, 2014 at 10:39 AM
I've modified my Folder.SearchMessageIds to allow for paging:
public long[] SearchMessageIds(string query = "ALL", int skip = -1, int count = -1)
            if (_client.SelectedFolder != this && !Select())
                throw new OperationFailedException("The folder couldn't be selected for search.");

            // Examine the folder before searching

            if (query.ToUpper() == "ALL" && _client.Behavior.SearchAllNotSupported)
                query = "SINCE 0000-00-00";

            IList<string> data = new List<string>();
            if (!_client.SendAndReceive(string.Format(ImapCommands.Search, query), ref data))
                throw new ArgumentException("The search query couldn't be processed");

            var result = Expressions.SearchRex.Match(data.FirstOrDefault(Expressions.SearchRex.IsMatch) ?? "");

            if (!result.Success)
                //throw new OperationFailedException("The data returned from the server doesn't match the requirements");
                return new long[0];

            IEnumerable<long> results = result.Groups[1].Value.Trim().Split(' ').Select(long.Parse).OrderByDescending(_ => _);
            if (skip > 0)
                results = results.Skip(skip);
            if (count > 0)
                results = results.Take(count);
            return results.ToArray();
I would like to see a modification like this in the main source so I would not have to have my own fork separated from other bug fixes and so on that come to the main repo
Dec 11, 2014 at 9:33 AM
Edited Dec 11, 2014 at 9:34 AM
MrX, wonderful, do you have a sample how to call this new method?
Dec 11, 2014 at 10:42 AM
I modified the methods Search and Download methods (Folder.cs) to accept and pass on the extra skip parameter, but i think you could definitely use this to download the ids and then pass then to Download yourself.

folder.Download(SearchMessageIds(query: "ALL", skip: pagenr*perpage, count: perpage))
Dec 11, 2014 at 10:59 AM
MrX, thank you very much.