Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EWS foreach all unread messages does not work

I need to loop through all unread messages in inbox and download first attachment for every email, my code works but only for first email, why ?

/* load all unread emails */
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(1));

/* loop through emails */
foreach (EmailMessage item in findResults)
{
    item.Load();

    /* download attachment if any */
    if (item.HasAttachments && item.Attachments[0] is FileAttachment) 
    {
        Console.WriteLine(item.Attachments[0].Name);
        FileAttachment fileAttachment = item.Attachments[0] as FileAttachment;

        /* download attachment to folder */
        fileAttachment.Load(downloadDir + fileAttachment.Name);
    }

    /* mark email as read */
    item.IsRead = true;
    item.Update(ConflictResolutionMode.AlwaysOverwrite);
}

Console.WriteLine("Done");

in my inbox it set the first email to read but the sript stops then and write "Done." to console window. Whats wrong ?

like image 999
Muflix Avatar asked Oct 24 '14 08:10

Muflix


2 Answers

The problem is that you're only requesting a single item from Exchange.

FindItemsResults<Item> findResults = service.FindItems(
    WellKnownFolderName.Inbox, 
    sf, 
    new ItemView(1));

The ItemView class constructor takes a page size as its parameter, which is defined as:

The maximum number of items the search operation returns.

So you're requesting a single item, which explains why your foreach completes after that one item.

To test this you can simply increase the pageSize to something more reasonable, like 100 or 1000.

But to fix it you should follow the idiomatic double-loop:

SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
FindItemsResults<Item> findResults;
ItemView view = new ItemView(100);
do {
    findResults = service.FindItems(WellKnownFolderName.Inbox, sf, view);
    foreach (var item in findResults.Items) {
        // TODO: process the unread item as you already did
    }
    view.Offset = findResults.NextPageOffset;
}
while (findResults.MoreAvailable);

Here we continue retrieving more items from Exchange (in batches of 100) as long as it tells us there are more items available.

like image 120
Frank van Puffelen Avatar answered Nov 09 '22 07:11

Frank van Puffelen


public void readMail() {

        ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
        service.Credentials = new WebCredentials("uname", "password", "domain");
        service.Url = new Uri("URL");
        System.Net.ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

        SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
        FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Inbox, searchFilter, new ItemView(int.MaxValue));
            foreach (EmailMessage item in findResults.Items)
            {

                    item.Load();
                    if (item.HasAttachments)
                    {
                        foreach (var i in item.Attachments)
                        {
                            try
                            {
                                FileAttachment fileAttachment = i as FileAttachment;
                                 fileAttachment.Load("C:\\Users\\xxxxx\\Desktop\\comstar\\Download\\test\\" + fileAttachment.Name);
                            }

                            catch(Exception e)
                            {
                                Console.Write(e);
                            }

                        }
                    }
                    //set mail as read 
                    item.IsRead = true;
                    item.Update(ConflictResolutionMode.AutoResolve);

                }

    }
like image 41
bapiraju Avatar answered Nov 09 '22 07:11

bapiraju