1

У меня есть служба Windows для чтения элементов календаря из Exchange и их хранения в базе данных моего приложения для каждого пользователя. Теперь интересно, как лучше всего отметить элемент на Exchange, который не будет получен в следующем запуске службы после его сохранения?EWS Managed Api - Получить элементы календаря только один раз

Я пытался добавить расширенное свойство элемента календаря и установить его значение, а затем поиск на основе его значение каждый раз, когда:

DateTime startDate = DateTime.Now; 
DateTime endDate = startDate.AddDays(60); 
const int NUM_APPTS = 60;  
// Set the start and end time and number of appointments to retrieve. 
CalendarView cView = new CalendarView(startDate, endDate, NUM_APPTS); 

Guid myPropertyId = new Guid("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"); 
ExtendedPropertyDefinition myExtendedProperty = new ExtendedPropertyDefinition(myPropertyId, "SyncFlag", MapiPropertyType.Boolean); 

// Limit the properties returned to the appointment's subject, start time, end time and the extended property. 
cView.PropertySet = new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End, AppointmentSchema.Location, myExtendedProperty); 

// Retrieve a collection of appointments by using the calendar view. 
List<SearchFilter> searchFilterCollection = new List<SearchFilter>(); 
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.Start, DateTime.Now)); 
searchFilterCollection.Add(new SearchFilter.IsEqualTo(AppointmentSchema.End, DateTime.Now.AddDays(60))); 

searchFilterCollection.Add(new SearchFilter.IsNotEqualTo(myExtendedProperty, true)); //Do not fetch already marked calendar items 

SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilterCollection); 

FindItemsResults<Item> appointments = service.FindItems(WellKnownFolderName.Calendar, searchFilter, cView); 

Поиск элементов календаря, используя этот код выдает это исключение:

Ограничения и порядок сортировки не могут быть указаны для CalendarView.

И я не уверен, что это лучший способ сделать это. Есть идеи?

Благодаря

ответ

2

Один из способов заключается в использовании метода SyncFolderItems. Он вернет элементы, которые были изменены с момента последнего вызова. Все, что вам нужно сделать, это сохранить синхронизацию «cookie» между каждым вызовом.

Вы также должны отфильтровать элементы назначения, созданные со времени вашего последнего вызова.

Этот снимок кода должен делать трюк.

static private void GetChangedItems() 
{ 
    // Path to cookie 
    string syncStateFileName = @"c:\temp\ewssyncstate.txt"; 

    try 
    { 
     var service = GetServiceAP(); 
     bool moreChangesAvailable = false; 

     do 
     { 
      string syncState = null; 


      if (File.Exists(syncStateFileName)) 
      { 
       // Read cookie 
       syncState = File.ReadAllText(syncStateFileName); 
      } 

      ChangeCollection<ItemChange> icc = service.SyncFolderItems(new FolderId(WellKnownFolderName.Calendar), PropertySet.FirstClassProperties, null, 10, SyncFolderItemsScope.NormalItems, syncState); 

      if (icc.Count == 0) 
      { 
       Console.WriteLine("There are no item changes to synchronize."); 
      } 
      else 
      { 
       syncState = icc.SyncState; 

       // Save cookie 
       File.WriteAllText(syncStateFileName, syncState); 

       moreChangesAvailable = icc.MoreChangesAvailable; 

       // Only get appointments that were created since last call 
       var createdItems = icc 
        .Where(i => i.ChangeType == ChangeType.Create) 
        .Select(i => i.Item as Appointment) 
        ; 

       if (createdItems.Any()) 
       { 
        service.LoadPropertiesForItems(createdItems, PropertySet.FirstClassProperties); 

        foreach (Appointment appointment in createdItems) 
        { 
         Console.WriteLine(appointment.Subject); 
        } 
       } 
      } 
     } 
     while (moreChangesAvailable); 

    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
}