Шаблоны повторения и EWS

Узнайте о шаблонах повторения и повторяющихся сериях в Exchange.

Повторяющаяся серия — это встреча или собрание, которое повторяется в соответствии с определенным шаблоном. Повторяющаяся серия может иметь определенное количество случаев или повторяться бесконечно. Кроме того, повторяющиеся серии могут иметь исключения, которые не следуют шаблону остальных случаев, и могут иметь случаи, которые были удалены из шаблона. Управляемый API и EWS можно использовать для работы с повторяющимися сериями и связанными с ними элементами календаря.

Периодические элементы календаря

Все элементы календаря попадают в одну из следующих четырех категорий:

  • Нестандартные элементы календаря

  • Повторяющиеся мастера

  • Возникновение в серии

  • Измененные вхождения в серии, известные как исключения

В этой статье мы посмотрим на три типа элементов календаря, которые являются частью повторяющейся серии.

Полезно понять, как реализуются повторяющиеся серии на Exchange сервере. Вместо создания отдельного отдельного элемента для каждого события в повторяющейся серии сервер создает только один фактический элемент в календаре, известный как повторяющийся мастер. Формат повторяющегося мастера очень похож на повторяющиеся встречи с добавлением сведений о шаблоне повторения. Затем сервер создает события на основе шаблона повторяемости в ответ на запросы клиентов о встрече с помощью процесса, называемого расширением. Эти генерируемые случаи не хранятся на сервере постоянно. Это важно понимать, так как способ поиска элементов календаря определяет, какие сведения вы получаете и происходит ли расширение.

Расписания повторения

Ключевым элементом повторяющейся серии, которая делает возможным расширение, является шаблон повторения. Шаблон повторения находится на повторяющейся мастер и описывает набор критериев для вычисления вхождений в зависимости от даты и времени повторяющегося мастера.

Таблица 1. Доступные шаблоны повторения

Класс управляемых API EWS Элемент EWS Примеры
Recurrence.DailyPattern
DailyRecurrence
Повторите каждый день.
Повторите каждый день.
Recurrence.MonthlyPattern
AbsoluteMonthlyRecurrence
Повторите каждый месяц на десятый день месяца.
Повторите каждые два месяца в двадцать первый день месяца.
Recurrence.RelativeMonthlyPattern
RelativeMonthlyRecurrence
Повторите во второй вторник каждого месяца.
Повторите в третий четверг месяца каждые три месяца.
Recurrence.RelativeYearlyPattern
RelativeYearlyRecurrence
Повторите каждый год в первый понедельник августа.
Recurrence.WeeklyPattern
WeeklyRecurrence
Повторите каждый понедельник.
Повторяйте каждый вторник и четверг каждую неделю.
Recurrence.YearlyPattern
AbsoluteYearlyRecurrence
Повторите 1 сентября каждый год.

Другой важный элемент сведений для шаблона повторения — это когда повторение заканчивается. Это может быть выражено как заданной датой, так и как без конца.

Таблица 2. Параметры окончания повторяющейся серии

Метод/свойство управляемого API EWS Элемент EWS Описание
Recurrence.NumberOfOccurrences
NumberedRecurrence
Значение этого свойства или элемента указывает количество вхождений.
Recurrence.EndDate
EndDateRecurrence
Последнее событие в серии относится к дате, указанной этим свойством или элементом, или до нее.
Recurrence.HasEnd
Recurrence.NeverEnds
NoEndRecurrence
Серия не имеет конца.

Расширенные и не расширенные представления

Использование метода FindAppointments в управляемом API EWS (или операция FindItem с элементом CalendarView в EWS) вызывает процесс расширения. Это скрывает повторяющиеся встречи с мастер-классами из набора результатов и вместо этого представляет расширенное представление этой повторяющейся серии. В набор результатов включены случаи и исключения для повторяющегося мастера, подпадающих под параметры представления календаря. И наоборот, с помощью метода FindItems в управляемом API EWS (или операции FindItem с элементом IndexedPageItemView или FractionalPageItemView в EWS) процесс расширения не вызывается, а вхождения и исключения не включаются. Рассмотрим пример сравнения этих двух методов.

Таблица 3. Методы и операции по поиску встреч

Метод управляемого API EWS Операция EWS Расширяет серию? Элементы, включенные в результаты
ExchangeService.FindAppointments
Операция FindItem с элементом CalendarView
Да
Нестандартные встречи, отдельные случаи повторяющихся серий и исключения из повторяющихся серий
ExchangeService.FindItems
Операция FindItem с элементом IndexedPageItemView или элементом FractionalPageItemView
Нет
Нестандартные встречи и повторяющиеся мастер-встречи

Сэди только что подписала сына для команды по плаванию. Команда практикует каждое утро среды в 8:30 утра, начиная со 2 июля, а последняя практика — 6 августа. Не желая забывать о практике, Сэди добавляет в календарь повторяющиеся встречи, чтобы напомнить ей.

Таблица 4. Повторяющиеся встречи Сэди

Поле назначения Значение
Subject
Практика команды swim
Начало
2 июля 2014 г. 08:30
End
2 июля 2014 г. 10:00
Повторы
Каждую среду
Последнее возникновение
6 августа 2014 г. 08:30

Краткий обзор календаря показывает, что команда будет иметь в общей сложности шесть практик. Однако в календаре нет шести отдельных элементов назначения. Вместо этого существует только одно повторяющееся мастер-назначение, представляющее серию.

Теперь давайте рассмотрим поиск встреч в календаре Сэди, которые происходят в течение июля. В следующем примере кода метод FindItems используется в Exchange управляемого API для создания неширокого представления календаря Сэди.

PropertySet propSet = new PropertySet(AppointmentSchema.Subject,
                                      AppointmentSchema.Location,
                                      AppointmentSchema.Start, 
                                      AppointmentSchema.End,
                                      AppointmentSchema.AppointmentType);
#region FindItems + ItemView method
ItemView itemView = new ItemView(100);
itemView.PropertySet = propSet;
List<SearchFilter> filterList = new List<SearchFilter>();
// Find appointments that start after midnight on July 1, 2014.
SearchFilter.IsGreaterThan startFilter = new SearchFilter.IsGreaterThan(AppointmentSchema.Start,
    new DateTime(2014, 7, 1));
// Find appointments that end before midnight on July 31, 2014
SearchFilter.IsLessThan endFilter = new SearchFilter.IsLessThan(AppointmentSchema.End,
    new DateTime(2014, 7, 31));
filterList.Add(startFilter);
filterList.Add(endFilter);
SearchFilter.SearchFilterCollection calendarFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, filterList);
// This results in a call to EWS.
FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Calendar, calendarFilter, itemView);
foreach(Item appt in results.Items)
{
    Console.WriteLine(appt.Subject);
}

Этот код приводит к следующему запросу операции FindItem с элементом IndexedPageItemView.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
    xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
    xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="Pacific Standard Time" />
    </t:TimeZoneContext>
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="calendar:Location" />
          <t:FieldURI FieldURI="calendar:Start" />
          <t:FieldURI FieldURI="calendar:End" />
          <t:FieldURI FieldURI="calendar:CalendarItemType" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="100" Offset="0" BasePoint="Beginning" />
      <m:Restriction>
        <t:And>
          <t:IsGreaterThan>
            <t:FieldURI FieldURI="calendar:Start" />
            <t:FieldURIOrConstant>
              <t:Constant Value="2014-07-01T07:00:00.000Z" />
            </t:FieldURIOrConstant>
          </t:IsGreaterThan>
          <t:IsLessThan>
            <t:FieldURI FieldURI="calendar:End" />
            <t:FieldURIOrConstant>
              <t:Constant Value="2014-07-31T07:00:00.000Z" />
            </t:FieldURIOrConstant>
          </t:IsLessThan>
        </t:And>
      </m:Restriction>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="calendar" />
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

Ответ сервера включает только один элемент , повторяющийся мастер, указанный в элементе CalendarItemType значения RecurringMaster. Значение элемента ItemId было сокращено для читаемости.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="939" MinorBuildNumber="16" Version="V2_11" 
        xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:FindItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:FindItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:RootFolder IndexedPagingOffset="1" TotalItemsInView="1" IncludesLastItemInRange="true">
            <t:Items>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADA5..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-02T15:30:00Z</t:Start>
                <t:End>2014-07-02T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>RecurringMaster</t:CalendarItemType>
              </t:CalendarItem>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

Теперь давайте сравним с расширенным представлением. В следующем примере кода метод FindAppointments используется в управляемом API EWS для создания расширенного представления календаря Сэди.

PropertySet propSet = new PropertySet(AppointmentSchema.Subject,
                                      AppointmentSchema.Location,
                                      AppointmentSchema.Start, 
                                      AppointmentSchema.End,
                                      AppointmentSchema.AppointmentType);
CalendarView calView = new CalendarView(new DateTime(2014, 7, 1),
    new DateTime(2014, 7, 31));
calView.PropertySet = propSet;
FindItemsResults<Appointment> results = service.FindAppointments(WellKnownFolderName.Calendar, calView);
foreach(Appointment appt in results.Items)
{
    Console.WriteLine(appt.Subject);
}

В этом коде приводится следующий запрос на операцию FindItem с элементом CalendarView.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
    xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
    xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="Pacific Standard Time" />
    </t:TimeZoneContext>
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="calendar:Location" />
          <t:FieldURI FieldURI="calendar:Start" />
          <t:FieldURI FieldURI="calendar:End" />
          <t:FieldURI FieldURI="calendar:CalendarItemType" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:CalendarView StartDate="2014-07-01T07:00:00.000Z" EndDate="2014-07-31T07:00:00.000Z" />
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="calendar" />
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

На этот раз ответ сервера включает пять инцидентов, по одному для каждой среды в июле. Элементы CalendarItemType для этих элементов имеют значение Occurrence. Обратите внимание, что повторяющийся мастер не присутствует в ответе. Значения элементов ItemId были сокращены для читаемости.

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="939" MinorBuildNumber="16" Version="V2_11" 
        xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:FindItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:FindItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:RootFolder TotalItemsInView="5" IncludesLastItemInRange="true">
            <t:Items>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADA6..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-02T15:30:00Z</t:Start>
                <t:End>2014-07-02T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>Occurrence</t:CalendarItemType>
              </t:CalendarItem>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADA7..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-09T15:30:00Z</t:Start>
                <t:End>2014-07-09T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>Occurrence</t:CalendarItemType>
              </t:CalendarItem>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADA8..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-16T15:30:00Z</t:Start>
                <t:End>2014-07-16T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>Occurrence</t:CalendarItemType>
              </t:CalendarItem>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADA9..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-23T15:30:00Z</t:Start>
                <t:End>2014-07-23T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>Occurrence</t:CalendarItemType>
              </t:CalendarItem>
              <t:CalendarItem>
                <t:ItemId Id="AAMkADAA..." ChangeKey="DwAAABYA..." />
                <t:Subject>Swim Team Practice</t:Subject>
                <t:Start>2014-07-30T15:30:00Z</t:Start>
                <t:End>2014-07-30T17:00:00Z</t:End>
                <t:Location>Neighborhood Swimming Pool</t:Location>
                <t:CalendarItemType>Occurrence</t:CalendarItemType>
              </t:CalendarItem>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

После того как у вас есть повторяющийся мастер, возникновение или исключение, вы всегда можете получить другие связанные элементы. При возникновении или исключении можно получить повторяющийся мастер и наоборот.

Работа с повторяющимися элементами календаря

Вы используете все те же методы и операции для работы с повторяющимися сериями, что и для работы с не повторяющимися элементами календаря. Разница в том, что в зависимости от элемента, используемого для вызова этих методов или операций, действия, которые вы принимаете, могут применяться к всей серии или к одному появлению. Действия, принятые на повторяющийся мастер будет применяться к всем событиям в серии, в то время как действия, принятые к одному возникновению или исключению, будут применяться только к этому возникновению или исключению.

В этом разделе:

См. также