【问题标题】:EWS Save Guid per Calendar Appointment每个日历约会的 EWS 保存指南
【发布时间】:2013-01-26 09:21:58
【问题描述】:

我需要为每个约会保存一个 Guid。 我尝试使用PolicyTagArchiveTag,但得到了一个,

"属性 PolicyTag 仅对 Exchange Exchange2013 或 更高版本。",

异常。

Exchange 2010 有类似的东西吗? 据我了解,appointment.ID 包含自生成的 ID。 我宁愿不使用它。 谢谢。

【问题讨论】:

    标签: c# guid exchangewebservices exchange-server-2010


    【解决方案1】:

    解决这个问题的一种方法是创建一个扩展属性,并为约会放置 guid,除非你从另一个约会中复制它,否则它不会改变(毕竟它只是一个属性)

    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;
    } 
    

    此解决方案在单个约会和使用 On Premises Exchange 的情况下非常有效。这里的问题是在线 Web 访问 (OWA) 中的会议,例如 Office 365,约会的属性是从组织者的原始约会中复制的,这些属性中有 AppoinmentID 是其中的扩展属性. 因此,为了避免这种麻烦,我们在组织者中将参加者的约会 id 设置为与原始的相似,并添加服务所有者(产生通知的服务)的电子邮件地址。 如果没有此解决方案,内部系统中的约会将具有与原始预订相似的 AppointmentID 并被视为一个,或者您可能有不同的两个具有相同 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
                }
    
            }
    

    【讨论】:

    • 感谢此代码。我试过了,效果很好。这是否意味着我不能使用约会唯一 ID 来更新、取消约会,因为它会在一段时间后改变?我可以使用此 GUID 绑定到会议然后更新、取消吗?
    • 关于唯一 id ,是的,您可以使用它,但是很难跟踪它,特别是如果约会移动到另一个文件夹,例如如果它被删除,尽管您收到的通知来自相同的约会,但 UniqueID 会改变,因此如果您将 uniqueID 映射为主键,则同一约会将有两行
    • 在会议的情况下,这是不同且棘手的部分。因为一旦组织者创建了一个会议并将其发送给与会者,它实际上将同一约会对象的副本发送给与会者。创建约会后,扩展属性(“AppointmentID”)当然将为空,然后将发送给与会者。在这种情况下(如果是新创建的)没关系,因为与会者将约会视为新约会并放置他们自己的 GUID。但!一旦组织者更改了会议,它将覆盖其余的所有属性,包括我们的“AppointmentID”!!!
    • 这个问题发生在 OWA(在线 Web 访问)的情况下,例如,如果您使用的是 Office 365。我没有遇到“本地”版本的 Outlook(我不知道为什么)无论如何,如果您希望我帮助您,请在遇到问题后发表新帖子,我将分享我使用的解决方案。所以更多的人可以受益,我得到更多的积分;)
    • 好吧,我在这里使用 Guid 来映射交换约会和内部数据库或内部日历中的约会。但是您始终可以在 Notifications 上使用 Unique ID 绑定到约会。我的解决方案解决了那些希望将 Exchange 约会与其系统中的约会同步的问题。我已经更新了上面的答案并添加了代码。现在这是我这边的解决方案,根据我们的需要,它可能与您需要它或解决它的方式不同。但是看看,试着理解我几乎在每一行后面都放了很多 cmets 的概念。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2015-09-26
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多