Patrones de periodicidad y EWS

Obtenga información sobre los patrones de periodicidad y las series periódicas en Exchange.

Una serie periódica es una cita o reunión que se repite según un patrón definido. Una serie periódica puede tener un número específico de repeticiones o puede repetirse indefinidamente. Además, una serie periódica puede tener excepciones que no siguen el patrón del resto de las repeticiones y pueden tener repeticiones que se han eliminado del patrón. Puede usar la API administrada ews y EWS para trabajar con series periódicas y sus elementos de calendario asociados.

Elementos de calendario periódicos

Todos los elementos del calendario se encuadrán en una de las cuatro categorías siguientes:

  • Elementos de calendario no periódicos

  • Patrones periódicos

  • Repeticiones en una serie

  • Repeticiones modificadas en una serie, conocidas como excepciones

En este artículo, veremos los tres tipos de elementos de calendario que forman parte de una serie periódica.

Es útil comprender cómo se implementan las series periódicas en el Exchange servidor. En lugar de crear un elemento distinto para cada repetición de una serie periódica, el servidor crea solo un elemento real en el calendario, conocido como patrón periódico. El formato de un patrón periódico es muy similar a una cita no periódica, con la adición de información de patrón de periodicidad. A continuación, el servidor genera repeticiones en función del patrón de periodicidad en respuesta a las solicitudes de cliente para obtener información de citas, mediante un proceso denominado expansión. Estas repeticiones generadas no se almacenan permanentemente en el servidor. Esto es importante comprender porque la forma en que busca elementos de calendario determina qué información recibe y si se produce la expansión.

Patrones de periodicidad

La pieza clave de una serie periódica que hace posible la expansión es el patrón de periodicidad. El patrón de periodicidad se encuentra en el patrón periódico y describe un conjunto de criterios para calcular las repeticiones en función de la fecha y hora del patrón periódico.

Tabla 1. Patrones de periodicidad disponibles

Clase de API administrada ews Elemento EWS Ejemplos
Recurrence.DailyPattern
DailyRecurrence
Repita todos los días.
Repita cada dos días.
Recurrence.MonthlyPattern
AbsoluteMonthlyRecurrence
Repita cada mes el décimo día del mes.
Repita cada dos meses el vigésimo primer día del mes.
Recurrence.RelativeMonthlyPattern
RelativeMonthlyRecurrence
Repita el segundo martes de cada mes.
Repita el tercer jueves del mes cada tres meses.
Recurrence.RelativeYearlyPattern
RelativeYearlyRecurrence
Repita el primer lunes de agosto de cada año.
Recurrence.WeeklyPattern
WeeklyRecurrence
Repita todos los lunes.
Repita cada martes y jueves cada dos semanas.
Recurrence.YearlyPattern
AbsoluteYearlyRecurrence
Repita el 1 de septiembre de cada año.

La otra información importante para un patrón de periodicidad es cuando finaliza la periodicidad. Esto puede expresarse como un número establecido de repeticiones, como una fecha de finalización o como no tener ningún final.

Tabla 2. Opciones para el final de una serie periódica

Método/propiedad de la API administrada ews Elemento EWS Descripción
Recurrence.NumberOfOccurrences
NumberedRecurrence
El valor de esta propiedad o elemento especifica el número de repeticiones.
Recurrence.EndDate
EndDateRecurrence
La última aparición de la serie se encuentra en o antes de la fecha especificada por esta propiedad o elemento.
Recurrence.HasEnd
Recurrence.NeverEnds
NoEndRecurrence
La serie no tiene fin.

Vistas expandida frente a vistas no expandida

El uso del método FindAppointments en la API administrada ews (o la operación FindItem con un elemento CalendarView en EWS) invoca el proceso de expansión. Esto oculta las citas maestras periódicas del conjunto de resultados y, en su lugar, presenta una vista expandida de esa serie periódica. En el conjunto de resultados se incluyen las repeticiones y excepciones del patrón periódico que se encuentran dentro de los parámetros de la vista de calendario. Por el contrario, el uso del método FindItems en la API administrada ews (o la operación FindItem con un elemento IndexedPageItemView o FractionalPageItemView en EWS), no invoca el proceso de expansión y no se incluyen las repeticiones y excepciones. Veamos un ejemplo comparando los dos métodos.

Tabla 3. Métodos y operaciones para buscar citas

Método de la API administrada de EWS Operación de EWS ¿Expande la serie? Elementos incluidos en los resultados
ExchangeService.FindAppointments
Operación FindItem con un elemento CalendarView

Citas no periódicas, repeticiones únicas de series periódicas y excepciones a series periódicas
ExchangeService.FindItems
Operación FindItem con un elemento IndexedPageItemView o un elemento FractionalPageItemView
No
Citas no periódicas y citas maestras periódicas

Sadie acaba de firmar a su hijo para el equipo de natación. El equipo tiene práctica todos los miércoles por la mañana a las 8:30 a.m., a partir del 2 de julio, siendo la última práctica el 6 de agosto. Sin querer olvidarse de la práctica, Sadie agrega una cita periódica a su calendario para recordarle.

Tabla 4. Cita periódica de Sadie

Campo Cita Valor
Subject
Práctica del equipo de natación
Inicio
2 de julio de 2014 8:30 a.m.
End
2 de julio de 2014 10:00 a.m.
Recurs
Todos los miércoles
Última aparición
6 de agosto de 2014 8:30 a.m.

Una vista rápida de un calendario muestra que el equipo tendrá un total de seis prácticas. Sin embargo, no hay seis elementos de cita distintos en el calendario. En su lugar, solo hay una cita maestra periódica que representa la serie.

Ahora veamos cómo encontrar citas en el calendario de Sadie que se produzcan en el mes de julio. En el siguiente ejemplo de código se usa el método FindItems en la API administrada de Exchange para generar una vista no expandida del calendario de Sadie.

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

Ese código da como resultado la siguiente solicitud de operación FindItem con un elemento 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>

La respuesta del servidor incluye solo un único elemento, el patrón periódico, indicado por el valor del elemento CalendarItemType de RecurringMaster. El valor del elemento ItemId se ha acortado para mejorar la legibilidad.

<?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>

Ahora vamos a comparar con una vista expandida. En el siguiente ejemplo de código se usa el método FindAppointments en la API administrada ews para crear una vista expandida del calendario de Sadie.

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

Este código da como resultado la siguiente solicitud de operación FindItem con un elemento 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>

Esta vez, la respuesta del servidor incluye cinco repeticiones, una por cada miércoles de julio. Los elementos CalendarItemType de estos elementos tienen un valor de Occurrence. Tenga en cuenta que el patrón periódico no está presente en la respuesta. Los valores de los elementos ItemId se han acortado para mejorar la legibilidad.

<?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>

Después de tener un patrón periódico, una repetición o una excepción, siempre puede recuperar los demás elementos relacionados. Dada una ocurrencia o excepción, puede recuperar el patrón periódico y viceversa.

Trabajar con elementos de calendario periódicos

Se usan todos los mismos métodos y operaciones para trabajar con series periódicas que se usan para trabajar con elementos de calendario no periódicos. La diferencia es que, según el elemento que use para invocar esos métodos u operaciones, las acciones que lleve a cabo se pueden aplicar a toda la serie o a una sola repetición. Las acciones realizadas en el patrón periódico se aplicarán a todas las repeticiones de la serie, mientras que las acciones realizadas en una única repetición o excepción solo se aplicarán a esa ocurrencia o excepción.

En esta sección

Consulte también