'Editing an appointment programmatically

I'm using Microsoft.Office.Interop.Outlook to load appointments into the interface and to edit appointments . I can load appointments completely fine, editing does work but not 100% of the time. Sometimes I get the error The operation cannot be performed because the message has been changed

May I ask is there a better approach for editing appointments to avoid The operation cannot be performed because the message has been changed error. Error occurs when trying to Save()

public Outlook.AppointmentItem EditOutlookAppointment(CustomAppointment appointment, int retries = 0)
{
    Outlook.AppointmentItem appointReturned = null;
    try
    {
        Outlook.Application outlookApp = new Outlook.Application();
        MAPIFolder calendarFolder = outlookApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);

        for (int i = calendarFolder.Items.Count; i > 0; i--)
        {
            var appointmentItem = ((Outlook.AppointmentItem)calendarFolder.Items[i]);

            if (appointmentItem.GlobalAppointmentID == appointment.UniqueId)
            {
                // set some properties
                appointmentItem.Subject    = appointment.Subject;
                appointmentItem.Body       = appointment.Body;
                appointmentItem.Location   = appointment.Location;            //Set the location
                appointmentItem.Start = appointment.Start;
                appointmentItem.End   = appointment.End; 
                appointmentItem.Save();
                return appointmentItem;
            }
        }
    }
    catch (Exception ex)
    {
            //Error message implementation here
    }
    return appointReturned;
}


Solution 1:[1]

Firstly, errors like that are unavoidable - it means the appointment was modified between the time Outlook opened it and the time you called Save. And since Outlook really likes to cache the appointments (it always caches the appointment being edited in Outlook or the previously edited appointment), that period of time can be quite large. This can happen if the appointment was modified by the Exchange server itself or by an incoming meeting update processing.

Secondly, looping through all items in the Calendar folder can be a huge performance problem. Unfortunately Outlook won't let you search (Items.Find/FindNext and Items.Restrict) on binary (PT_BINARY) properties such as GlobalAppointmentID. You'd need to use Extended MAPI (C++ or Delphi) or Redemption (I am its author - any language) for this: (RDOtems.Find/FindNext/Restrict in Redemption allow to search on binary properties).

UPDATE. The following should work using Redemption (off the top of my head):

publicRedemption.RDOAppointmentItem EditOutlookAppointment(CustomAppointment appointment, int retries = 0)
{
    try
    {
        Outlook.Application outlookApp = new Outlook.Application();
        Redemption.RDOSession session = new Redemption.RDOSession();
        session.MAPIOBJECT = outlookApp.Session.MAPIOBJECT; //share the Outlook session
        RDOFolder calendarFolder = session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);
        Redemption.RDOAppointmentItem appointmentItem  = calendarFolder.Items.Find("GlobalAppointmentID = '"+appointment.UniqueId + "'");

        if (appointmentItem != null)
        {
                // set some properties
                appointmentItem.Subject    = appointment.Subject;
                appointmentItem.Body       = appointment.Body;
                appointmentItem.Location   = appointment.Location;            //Set the location
                appointmentItem.Start = appointment.Start;
                appointmentItem.End   = appointment.End; 
                appointmentItem.Save();
                return appointmentItem;
        }
    }
    catch (Exception ex)
    {
            //Error message implementation here
    }
    return null;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1