Вопрос

I need to save a Guid per every Appointment. I've tried to use PolicyTag and ArchiveTag,but got an ,

"The property PolicyTag is valid only for Exchange Exchange2013 or later versions.",

exception.

Does we have something similar for Exchange 2010? As i understand there is appointment.ID that contains self-generated id. I prefer not to use it. Thank you.

Это было полезно?

Решение

A way to deal with this problem is to create an extended property, and put guid for the appointment, and it wont change unless you made a copy from another appointment (after all it is just a property)

private static readonly PropertyDefinitionBase AppointementIdPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "AppointmentID", MapiPropertyType.String);
public static PropertySet PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, AppointementIdPropertyDefinition);


//Setting the property for the appointment 
 public static void SetGuidForAppointement(Appointment appointment)
{
    try
    {
        appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, Guid.NewGuid().ToString());
        appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
    }
    catch (Exception ex)
    {
        // logging the exception
    }
}

//Getting the property for the appointment
 public static string GetGuidForAppointement(Appointment appointment)
{
    var result = "";
    try
    {
        appointment.Load(PropertySet);
        foreach (var extendedProperty in appointment.ExtendedProperties)
        {
            if (extendedProperty.PropertyDefinition.Name == "AppointmentID")
            {
                result = extendedProperty.Value.ToString();
            }
        }
    }
    catch (Exception ex)
    {
     // logging the exception
    }
    return result;
} 

This solution works very well in case of single appointments and in case of using On Premises Exchange. The problem here is in case of meetings in the Online Web Access (OWA), such as Office 365, the properties of the appointments are copied from the original appointment from the organizer, among these properties are the extended properties which the AppoinmentID is among them. Therefore to avoid this trouble, we make the appointment id of the attendee similar one to the original in the organizer, and just add the email address for the service owner (the service that produced the notification). Without this solution , the appointment in the internal system will have similar AppointmentID to the original booking and it will be considered as one, or you might have different two appointments with the same ID.

 private static void SetGuidForMeetingAppiontment(Appointment appointment)
        {
            var log = "";

            try
            {
                if (!appointment.IsMeeting) return;
                if (appointment.Service.ImpersonatedUserId == null) return;

                /*
                 * The only tricky case is that if the appointment is created at the attendee with no Guid.
                 * In this case the application should look for the original appointment from the organizer's side, and get its guid, to paste it in the new booking 
                 * from the attendee side, and add the attendee emailAddress. 
                 */
                if (GetGuidForMeetingAppointement(appointment).Length <= 36)
                {
                    // If it was an attendee, then look for the original appointment from the organizer's service
                    if (appointment.Service.ImpersonatedUserId.Id != appointment.Organizer.Address)
                    {

                        log += "1/5 Getting the original event of the meeting\n";
                        if (ExchangeLiteService.Services.ContainsKey(appointment.Organizer.Address))
                        {
                            //  FindItemsResults<Appointment> originalAppointments;
                            var originalAppointments = ExchangeLiteService.Services[appointment.Organizer.Address].FindAppointments(WellKnownFolderName.Calendar, new CalendarView(appointment.Start, appointment.End, 1));
                            if (originalAppointments == null) return; //there must be an original appointment. 
                            if (!originalAppointments.Any()) return; //there must be an original appointment. 
                            var originalAppointment = originalAppointments.First(); // there should be only one appointment at a specifict time and date. 

                            log += "2/5 Getting the Guid for the original event of the meeting\n";
                            var originalAppointmentID = GetGuidForMeetingAppointement(originalAppointment);
                            if (string.IsNullOrEmpty(originalAppointmentID)) return; // the original appointment must have a guid already.

                            var orignalAppointmentIDGuid = originalAppointmentID.Substring(0, 36);

                            log += "3/5 Attaching the email address to the guid extracted\n";
                            var newAppointmentID = orignalAppointmentIDGuid + "_" + appointment.Service.ImpersonatedUserId.Id;

                            log += "4/5 Setting the new Guid to the meeting appointment\n";
                            appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, newAppointmentID);

                            log += "5/5 Updateing the meeting appointment\n";
                            appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
                        }
                        else //Then the user is invited from an organizer outside the system.
                        {
                            // Delete if there are anything similar 
                            ExchangeLiteService.OnCallDeleteBookingFromInternal(appointment.Service.ImpersonatedUserId.Id, appointment.Start, appointment.End);

                            //Assign a new 
                            var appointmentIDGuid = Guid.NewGuid().ToString();
                            var newAppointmentID = appointmentIDGuid + "_" + appointment.Service.ImpersonatedUserId.Id;
                            appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, newAppointmentID);
                            appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);

                        }
                        //Get only the guid part of it (without the address of the organizer) 
                    }
                    else // if he was the organizer 
                    {
                        log += "If it was new meeting appointment and the notification from the organizer\n";
                        var appointmentIDGuid = Guid.NewGuid().ToString();
                        var newAppointmentID = appointmentIDGuid + "_" + appointment.Service.ImpersonatedUserId.Id;
                        appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, newAppointmentID);
                        appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
                    }
                }
                else
                {
                    log += "If it was an updated meeting appointment and has Guid already\n";
                    var appointmentID = GetGuidForMeetingAppointement(appointment);
                    var appointmentIDGuid = appointmentID.Substring(0, 36);
                    var newAppointmentID = appointmentIDGuid + "_" + appointment.Service.ImpersonatedUserId.Id;
                    appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, newAppointmentID);
                    appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
                }
            }
            catch (Exception ex)
            {
                //Logging the exception
            }

        }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top