2013-02-11 2 views
3

모든 약속마다 안내를 저장해야합니다.EWS 일정 당 안내 저장 약속

, 내가 PolicyTagArchiveTag를 사용하는 것을 시도했다, 그러나 얻었다 "속성 PolicyTag은 Exchange Exchange2013 또는 이후 버전에 유효합니다."

예외입니다.

Exchange 2010과 비슷한 점이 있습니까? 자체 생성 ID가 포함 된 appointment.ID이 있다는 것을 알고 있습니다. 나는 그것을 사용하지 않는 것을 선호한다. 감사합니다.

답변

4

이 문제를 해결하기위한 방법은 확장 속성을 생성하고, 약속 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; 
} 
(결국 그냥 속성입니다) 변경 실 거예요

이 솔루션은 단일 약속의 경우와 온 프레미스 Exchange를 사용하는 경우에 매우 효과적입니다. 여기서 문제는 Office 365와 같은 OWA (Online Web Access)의 모임의 경우 약속의 속성이 주최자의 원래 약속에서 복사 된 것이며 이러한 속성 중 AppoinmentID가 포함 된 확장 속성입니다 . 따라서이 문제를 피하기 위해 주최자의 약속 ID를 주최자의 오리지널 ID와 유사하게 만들고 서비스 소유자 (알림을 생성 한 서비스)의 전자 메일 주소를 추가하기 만합니다. 이 솔루션을 사용하지 않으면 내부 시스템의 약속이 원래 예약과 비슷한 AppointmentID를 가지게되어 하나의 ID로 간주되거나 동일한 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 
      } 

     } 
+0

이 코드를 이용해 주셔서 감사합니다. 나는 그것을 시도하고 그것은 아주 잘하고있다. 즉, 일정 uniqueId를 사용하여 업데이트 할 수 없다는 뜻입니까, 잠시 후에 변경 될 예정이므로 약속을 취소 할 수 있습니까? 이 GUID를 사용하여 모임에 바인딩 한 다음 업데이트하고 취소 할 수 있습니까? – Morano88

+1

고유 ID에 관해서는 네, 사용할 수는 있지만 약속을 다른 폴더로 옮긴 경우에는 추적하기가 매우 어렵습니다 (예 : 삭제 된 경우). 알림은 동일한 약속이지만 UniqueID 따라서 고유 ID를 기본 키로 매핑하는 경우 동일한 약속에 대해 두 행을 갖게됩니다. – BraveHeart

+2

모임의 경우에는 다른 부분과 까다로운 부분입니다. 주최자가 모임을 만들어 참석자에게 보내면 실제로 동일한 약속 개체의 복사본을 참석자에게 보냅니다. 약속이 생성되면 확장 속성 ("AppointmentID")이 비어 있고 참석자에게 전송됩니다. 이 경우 (새로 만든 경우) 참석자가 약속을 새 것으로 처리하고 자신의 GUID를 넣기 때문에이 작업은 정상입니다. 그러나! 일단 주최자가 회의를 변경하면 우리의 "AppointmentID"를 포함하여 나머지 모든 속성이 무시됩니다 !!! – BraveHeart