2012-06-27 2 views
3

신뢰할 수있는 도메인에 살고 해당 도메인의 Exchange 서버에서 사서함 일정 모음을 모니터링하고 약속을 동기화하는 데 필요한 앱을 작성하고 있습니다. 하나 이상의 다른 서버에있는 다른 사서함으로. 동기화되는 사서함은이 응용 프로그램의 사용자가 관리하는 내부 매핑 테이블 (sqlce)에 정의되어 있습니다.EWS Managed API SyncFolderItems 항목을 업데이트하고 삭제/추적하는 방법

문제는 원격 약속을 추적하여 필요한 경우 업데이트하거나 삭제할 수있는 방법을 찾지 못하는 것입니다. 원격 서버에 약속을 만든 후에는 로컬 Exchange 서버에서 동기화 폴더 항목 호출에 의해 반환 된 것과 일치하지 않는 새 itemid가 있습니다. 항목이 변경되거나 삭제되었을 수 있으므로 시작 시간/제목별로 항목을 찾을 수 없습니다.

내 동기화 방법이 아래에 있습니다. 전적으로 잘못된 방식일까요? 아니면 SyncFolderItems 메서드를 사용하는 더 좋은 방법이 있습니까?

내가 지금까지 내 문제를 해결하기 위해 내놓았던 가장 좋은 방법은 원격 약속의 ItemID를 로컬 약속의 속성으로 저장하는 것입니다. 그러나 이것도 내가 모르기 때문에 작동하지 않을 것입니다. 속성은 삭제 후에도 유지됩니까? 도와주세요!

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Exchange.WebServices.Data; 
using System.Net; 

namespace ProExchangeSync2012 
{ 
    class ExchangeWebServiceMethods 
    { 

    public string ProExchangeSyncCalendars(string LocalMailbox 
               ,string RemoteMailbox 
               ,string SyncState  
               ,ExchangeService RemoteService 
               ,ExchangeService LocalService 
               ) 
    { 
     //if SyncState is empty string set to null 
     if (SyncState.ToString().Length == 0) 
     { SyncState = null; } 

     ExchangeService LocalExchangeService = LocalService; 
     ExchangeService RemoteExchangeService = RemoteService; 
     RemoteExchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,RemoteMailbox); 


     //Folders and mailboxes to pass to the webservice in SyncItems call. 
     Mailbox DonorMailBox = new Mailbox(LocalMailbox); 
     Mailbox DestinationMailBox = new Mailbox(RemoteMailbox); 
     FolderId DonorFolder = new FolderId(WellKnownFolderName.Calendar, DonorMailBox); 
     FolderId DestinationFolder = new FolderId(WellKnownFolderName.Calendar, DestinationMailBox); 

     //Create a ChangeCollection object and call syncfolderitems on local exchange service. 
     ChangeCollection<ItemChange> ItemChanges 
     = LocalExchangeService.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar, DonorMailBox) //PASS IN THE MAILBOX HERE> 
             , PropertySet.FirstClassProperties 
             , null 
             , 512 
             , SyncFolderItemsScope.NormalItems 
             , SyncState 
             ); 


     //Store the SyncState 
     SyncState = ItemChanges.SyncState; 

     //Fetch all the required properties of the items 
     //LocalService.LoadPropertiesForItems(ItemChanges, PropertySet.FirstClassProperties); 

     if (ItemChanges.Count == 0) 
     { 
      Console.WriteLine("There are no items to synchronize."); 
     } 
     else 
     { 
      foreach (ItemChange ic in ItemChanges) 
      { 
       if (ic.ChangeType == ChangeType.Create) 
       { 
        Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId); 
        Appointment rappointment = new Appointment(RemoteExchangeService); 
        rappointment.Subject = lappointment.Subject; 
        rappointment.Start = lappointment.Start; 
        rappointment.Body = lappointment.Body; 
        rappointment.End = lappointment.End; 
        rappointment.Location = lappointment.Location; 
        rappointment.Save(); 

       } 

       else if (ic.ChangeType == ChangeType.Update) 
       { 
        //Bind to the local appointment and get the start date 
        Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId); 
        DateTime StartDate = lappointment.Start; 
        ItemId ItemToUpdate = ItemIDSearch(RemoteExchangeService,StartDate,lappointment.Subject); 
        //Bind to the remote appointment using ItemToUpdate & update all the details 
        //this is is less intensive than comparing the appointments for changes. 
        Appointment rappointment = Appointment.Bind(RemoteExchangeService, ItemToUpdate); 
        rappointment.Subject = lappointment.Subject; 
        rappointment.Start = lappointment.Start; 
        rappointment.Body = lappointment.Body; 
        rappointment.End = lappointment.End; 
        rappointment.Location = lappointment.Location; 
        rappointment.Save(); 

       } 
       else if (ic.ChangeType == ChangeType.Delete) 
       { 
        Appointment lappointment = Appointment.Bind(LocalExchangeService, ic.ItemId.UniqueId); 
        DateTime StartDate = lappointment.Start; 
        ItemId ItemToUpdate = ItemIDSearch(RemoteExchangeService, StartDate, lappointment.Subject); 
        Appointment rappointment = Appointment.Bind(RemoteExchangeService, ic.ItemId.UniqueId); 
        rappointment.Delete(DeleteMode.MoveToDeletedItems); 
       } 

      } 
     } 


     return SyncState; 
    } 
    //End of Sync Method 

    //Below method returns a single itemid from exchange service based on start datetime of an appointment in a mailbox. 
    public ItemId ItemIDSearch(ExchangeService ExchangeService, DateTime AppointmentStart, string subject) 
    { 
     ItemId FoundItem; 
     ItemView iv = new ItemView(1000); 
     iv.Traversal = ItemTraversal.Associated; 

     SearchFilter.SearchFilterCollection searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And); 
     searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Subject,subject)); 
     searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Start, AppointmentStart)); 

     FindItemsResults<Item> fiitems = ExchangeService.FindItems(WellKnownFolderName.Calendar, searchFilterCollection, iv); 

     if (fiitems.Items.Count == 1)//if we only get one result do the work else return null 
     { 
      FoundItem = fiitems.Items[0].Id; 
     } 

     FoundItem = null; 

     return FoundItem;   
    } 


} 
    } 

답변

3

그래서 Exchange 웹 서비스의 메시아에서 온 모든이에 대한 최종 해결책은, 글렌 저울, 나는 "CleanGlobalObjectId"저장된 것을 나는 함께 내 내부 데이터베이스에 맞추지 된 약속 EWS EWS SyncFolderItems 메서드를 호출 할 때 반환되는 UniqueId입니다.

약속의 확장 속성 인 CleanGlobalObjectId를 사용하면이 속성의 값이 절대로 변경되지 않기 때문에 하드 지정이 삭제 된 경우에도 항상 서버에서 특정 약속을 찾을 수있었습니다.