1

Relating to a batch update question I asked previously about using a single update to mark as read all the unread emails, I could use ExchangeService.UpdateItems according to Jason's answer.

So I modified accordingly:

Folder.Bind(Service, WellKnownFolderName.Inbox);

SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
    new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));

//ItemView limits the results to numOfMails2Fetch items
FindItemsResults<Item> foundItems = Service.FindItems(WellKnownFolderName.Inbox, sf,
    new ItemView(numOfMails2Fetch));

if (foundItems.TotalCount > 0)
{
    List<EmailMessage> emailsList = new List<EmailMessage>(foundItems.TotalCount);

    foundItems.Items.ToList().ForEach(item =>
    {
        var iEM = item as EmailMessage;
        // update properties BEFORE ADDING
        iEM.IsRead = true;

        //DO NOT UPDATE INSIDE THE LOOP,I.E. DO NOT USE:
        //iEM.Update(ConflictResolutionMode.AutoResolve);

        //add the EmailMessage to the list
        emailsList.Add(iEM);
    });

    // fetches the body of each email and assigns it to each EmailMessage
    Service.LoadPropertiesForItems(emailsList,PropertySet.FirstClassProperties);

    // Batch update all the emails
    ServiceResponseCollection<UpdateItemResponse> response =
      Service.UpdateItems(emailsList,
       WellKnownFolderName.Inbox, ConflictResolutionMode.AutoResolve, 
       MessageDisposition.SaveOnly, null);
    // ABOVE LINE CAUSES EXCEPTION
    return emailsList;
}

Notice that I pulled up the IsRead attribution, placed it before adding the item to the list. The exception is the following:

This operation can't be performed because one or more items are new or unmodified

From MSDN's example it seems setting IsRead to true should be enough, so why are the items not being considered for the batch update?

Community
  • 1
  • 1
Armfoot
  • 4,663
  • 5
  • 45
  • 60
  • FYI it is crazy hard reading your code Im not surprised you are getting issues as it doesn't even read properly.... just for each over the collection. – Seabizkit Feb 04 '16 at 18:15
  • Are you not able to drop the outer loop tho and just have a foreach over the return back from Service.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(numOfMails2Fetch)); – Seabizkit Feb 04 '16 at 18:50
  • @Seabizkit There is only one loop, I adjusted the code for improved readability. Jason below identified the problem, it was due to the order of the `LoadPropertiesForItems` and `UpdateItems`, I just placed the load method after (reversed it) and voilá, problem solved. – Armfoot Feb 04 '16 at 19:46

2 Answers2

1

At first guess it's the LoadPropertiesForItems call you make outside the loop. This likely overwrites your changes by loading the values back from the server.

Jason Johnston
  • 17,194
  • 2
  • 20
  • 34
  • Thanks again Jason! It was exactly that, I switched the order of those 2 lines and worked as expected. Lol, should have thought of that before, the load is a kind of a reset to the previous status of the list. – Armfoot Feb 04 '16 at 18:44
0

This is by no means the answer... I just wanted to check if you could format it something like so

    Folder.Bind(Service, WellKnownFolderName.Inbox);

    var sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));

    //ItemView limits the results to numOfMails2Fetch items
    var foundItems = Service.FindItems(WellKnownFolderName.Inbox, sf, new ItemView(numOfMails2Fetch)).ToList();

    // fetches the body of each email and assigns it to each EmailMessage
    Service.LoadPropertiesForItems(foundItems,PropertySet.FirstClassProperties);

    //List<EmailMessage> emailsList = new List<EmailMessage>();
    foreach(var item in foundItems)
    {
      var iEM = item as EmailMessage;
      if(iEM != null)
          iEM.IsRead = true;
      //emailsList.Add(iEM);
    }

    // Batch update all the emails
    var response = Service.UpdateItems(foundItems, WellKnownFolderName.Inbox, ConflictResolutionMode.AutoResolve, MessageDisposition.SaveOnly, null);

    return foundItems;
}
Seabizkit
  • 2,417
  • 2
  • 15
  • 32