Performing pages searches by using the EWS Managed API 2.0

You can use the Microsoft Exchange Web Services (EWS) Managed API to perform paged searches.

Last modified: October 13, 2012

Applies to: EWS Managed API | Exchange Server 2007 Service Pack 1 (SP1) | Exchange Server 2010

Note: This content applies to the EWS Managed API 2.0 and earlier versions. For the latest information about the EWS Managed API, see Web services in Exchange.

To perform paged searches

  1. Set the offset and pageSize, and set the flag that indicates whether there are more items to page. The pageSize indicates the maximum number of items the search operation returns.

    int offset = 2;
    const int pageSize = 3;
    bool MoreItems = true;
    
  2. Iteratively page through the search results until there are no remaining items.

    while (MoreItems)
    {....}
    

To iterate through the search results until MoreItems is false

  1. Write out the page number.

    Console.WriteLine("Page: " + offset / pageSize);
    
  2. Set the ItemView object with the page size, offset, and result set ordering instructions. In the following example, the items in the result set are ordered by the DisplayName property in ascending order.

    ItemView view = new ItemView(pageSize, offset, OffsetBasePoint.Beginning);
    view.OrderBy.Add(ContactSchema.DisplayName, SortDirection.Ascending);
    
  3. Send the search request to search the Contacts folder and get the first page of results.

    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Contacts, view);
    
  4. Process each item that was returned in the paged results.

    foreach (Item myItem in findResults.Items)
    {
       if (myItem is Contact)
          Console.WriteLine("Contact name: " + (myItem as Contact).DisplayName);
       else
          Console.WriteLine("Non-contact item found.");
    }
    
  5. Set the MoreItems flag to false if there are no more items to page.

    if (!findResults.MoreAvailable)
       MoreItems = false;
    
  6. Update the offset by the page size if there are additional pages of results.

    if (MoreItems)
       offset = offset + pageSize;
    

Example

The following example shows how to perform a paged search with a page size of three that starts after the second item of the search results.

// Set the offset for the paged search.
int offset = 0;

// Set the page size.
const int pageSize = 3;

// Set the flag that indicates whether to continue iterating through additional pages.
bool MoreItems = true;

// Continue paging while there are more items to page.
while (MoreItems)
{
    // Write out the page number.
    Console.WriteLine("Page: " + offset / pageSize);

    // Set the ItemView with the page size, offset, and result set ordering instructions.
    ItemView view = new ItemView(pageSize, offset, OffsetBasePoint.Beginning);
    view.OrderBy.Add(ContactSchema.DisplayName, SortDirection.Ascending);

    // Send the search request and get the search results.
    FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.Contacts, view);

    // Process each item.
    foreach (Item myItem in findResults.Items)
    {
        if (myItem is Contact)
        {
            Console.WriteLine("Contact name: " + (myItem as Contact).DisplayName);
        }
        else
        {
            Console.WriteLine("Non-contact item found.");
        }
    }

    // Set the flag to discontinue paging.
    if (!findResults.MoreAvailable)
        MoreItems = false;

    // Update the offset if there are more items to page.
    if (MoreItems)
        offset += pageSize;
}
' Set the offset for the paged search.
Dim offset As Integer = 2

' Set the page size.
Dim pageSize As Integer = 3

' Set the flag that indicates whether to continue iterating through additional pages.
Dim MoreItems As Boolean = True

' Continue paging while there are more items to page.
Do While MoreItems
    ' Write out the page number.
    Console.WriteLine("Page: " & Int(offset / pageSize))

    ' Set the ItemView with the page size, offset, and result set ordering instructions.
    Dim view As New ItemView(pageSize, offset, OffsetBasePoint.Beginning)
    view.OrderBy.Add(ContactSchema.DisplayName, SortDirection.Ascending)

    ' Send the search request and get the search results.
    Dim findResults As FindItemsResults(Of Item) = service.FindItems(WellKnownFolderName.Contacts, view)

    ' Process each item.
    For Each item As Item In findResults.Items
        If TypeOf item Is Contact Then
            Console.WriteLine("Contact name: " & TryCast(item, Contact).DisplayName)
        Else
            Console.WriteLine("Non-contact item found.")
        End If
    Next

    ' Set the flag to discontinue paging.
    If Not findResults.MoreAvailable Then
        MoreItems = False
    End If

    ' Update the offset if there are more items to page.
    If MoreItems Then
        offset += pageSize
    End If
Loop

The following example shows the XML that is sent by the FindItems method.

<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="Exchange2010" />
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>AllProperties</t:BaseShape>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="3" Offset="5" BasePoint="Beginning" />
      <m:SortOrder>
        <t:FieldOrder Order="Ascending">
          <t:FieldURI FieldURI="contacts:DisplayName" />
        </t:FieldOrder>
      </m:SortOrder>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="contacts" />
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

The following example shows the XML that is returned by using the FindItems method. The ItemId and ChangeKey attributes have been shortened to preserve readability. The length of the request is limited to the page size. If there are more items returned than the PageSize value, there are multiple responses. The following is only one response and has three items.

<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="14" 
        MinorVersion="0" 
        MajorBuildNumber="639" 
        MinorBuildNumber="20" 
        Version="Exchange2010" 
        xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xm=""lns:xsd="http://www.w3.org/2001/XMLSchema" />
  </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="5" TotalItemsInView="7" IncludesLastItemInRange="false">
            <t:Items>
              <t:Contact>
                <t:ItemId Id="AQMkAGEyYzQ" ChangeKey="EQAAABYAAA" />
                <t:ParentFolderId Id="AQMkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAuAAADxdu66sOO90WjgEbv6Ra2VAEAwmVnt/opXEiv3zVwB"+hrOAAAAyAAAAA=" 
                   ChangeKey="AQAAAA==" />
                <t:ItemClass>IPM.Contact</t:ItemClass>
                <t:Subject>New Subject?</t:Subject>
                <t:Sensitivity>Normal</t:Sensitivity>
                <t:DateTimeReceived>2009-10-13T17:29:11Z</t:DateTimeReceived>
                <t:Size>147</t:Size>
                <t:Importance>Normal</t:Importance>
                <t:IsSubmitted>false</t:IsSubmitted>
                <t:IsDraft>true</t:IsDraft>
                <t:IsFromMe>false</t:IsFromMe>
                <t:IsResend>false</t:IsResend>
                <t:IsUnmodified>false</t:IsUnmodified>
                <t:DateTimeSent>2009-10-13T17:29:11Z</t:DateTimeSent>
                <t:DateTimeCreated>2009-10-13T17:29:11Z</t:DateTimeCreated>
                <t:DisplayCc />
                <t:DisplayTo />
                <t:HasAttachments>false</t:HasAttachments>
                <t:Culture>en-US</t:Culture>
                <t:EffectiveRights>
                  <t:CreateAssociated>false</t:CreateAssociated>
                  <t:CreateContents>false</t:CreateContents>
                  <t:CreateHierarchy>false</t:CreateHierarchy>
                  <t:Delete>true</t:Delete>
                  <t:Modify>true</t:Modify>
                  <t:Read>true</t:Read>
                </t:EffectiveRights>
                <t:LastModifiedName>E14UserTwo</t:LastModifiedName>
                <t:LastModifiedTime>2009-10-13T17:29:11Z</t:LastModifiedTime>
                <t:IsAssociated>false</t:IsAssociated>
                <t:WebClientReadFormQueryString>
                  ?ae=Item&amp;a=Open&amp;t=IPM.
                  Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAAA
                  gAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZL6AAAR&amp;exvsurl=1</t:WebClientReadFormQuer
yString>
                  <t:WebClientEditFormQueryString>
                    ?ae=Item&amp;a=Open&amp;s=Draf
                    t&amp;t=IPM.Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXA
                    H6Gs4AAAAAAAgAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZL6AAAR&amp;exvsurl=1</t:WebClient
EditFormQueryString>
                    <t:ConversationId Id="AAQkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAQANQdjNmPALIE6YAJmOz4Qn4=" />
                    <t:FileAs />
                    <t:FileAsMapping>None</t:FileAsMapping>
                    <t:DisplayName>Beebe</t:DisplayName>
                    <t:GivenName>Beebe</t:GivenName>
                    <t:MiddleName>Middle</t:MiddleName>
                    <t:Nickname>Ann</t:Nickname>
                    <t:CompleteName>
                      <t:FirstName>Beebe</t:FirstName>
                      <t:MiddleName>Middle</t:MiddleName>
                      <t:LastName>Beebe</t:LastName>
                      <t:FullName>Beebe</t:FullName>
                      <t:Nickname>Ann</t:Nickname>
                    </t:CompleteName>
                    <t:Surname>Beebe</t:Surname>
                  </t:Contact>
              <t:Contact>
                <t:ItemId Id="AQMkAGEyYzQ" ChangeKey="EQAAABYAAA" />
                <t:ParentFolderId Id="AQMkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAuAAADxdu66sOO90WjgEbv6Ra2VAEAwmVnt/opXEiv3zVwB"+hrOAAAAyAAAAA=" 
                   ChangeKey="AQAAAA==" />
                <t:ItemClass>IPM.Contact</t:ItemClass>
                <t:Subject>New Subject?</t:Subject>
                <t:Sensitivity>Normal</t:Sensitivity>
                <t:DateTimeReceived>2009-10-13T17:20:41Z</t:DateTimeReceived>
                <t:Size>147</t:Size>
                <t:Importance>Normal</t:Importance>
                <t:IsSubmitted>false</t:IsSubmitted>
                <t:IsDraft>true</t:IsDraft>
                <t:IsFromMe>false</t:IsFromMe>
                <t:IsResend>false</t:IsResend>
                <t:IsUnmodified>false</t:IsUnmodified>
                <t:DateTimeSent>2009-10-13T17:20:41Z</t:DateTimeSent>
                <t:DateTimeCreated>2009-10-13T17:20:41Z</t:DateTimeCreated>
                <t:DisplayCc />
                <t:DisplayTo />
                <t:HasAttachments>false</t:HasAttachments>
                <t:Culture>en-US</t:Culture>
                <t:EffectiveRights>
                  <t:CreateAssociated>false</t:CreateAssociated>
                  <t:CreateContents>false</t:CreateContents>
                  <t:CreateHierarchy>false</t:CreateHierarchy>
                  <t:Delete>true</t:Delete>
                  <t:Modify>true</t:Modify>
                  <t:Read>true</t:Read>
                </t:EffectiveRights>
                <t:LastModifiedName>E14UserTwo</t:LastModifiedName>
                <t:LastModifiedTime>2009-10-13T17:20:41Z</t:LastModifiedTime>
                <t:IsAssociated>false</t:IsAssociated>
                <t:WebClientReadFormQueryString>
                  ?ae=Item&amp;a=Open&amp;t=IPM.
                  Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAAA
                  gAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZLyAAAR&amp;exvsurl=1</t:WebClientReadFormQuer
yString>
                  <t:WebClientEditFormQueryString>
                    ?ae=Item&amp;a=Open&amp;s=Draf
                    t&amp;t=IPM.Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXA
                    H6Gs4AAAAAAAgAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZLyAAAR&amp;exvsurl=1</t:WebClient
EditFormQueryString>
                    <t:ConversationId Id="AAQkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAQANQdjNmPALIE6YAJmOz4Qn4=" />
                    <t:FileAs />
                    <t:FileAsMapping>None</t:FileAsMapping>
                    <t:DisplayName>Hagege</t:DisplayName>
                    <t:GivenName>Hagege</t:GivenName>
                    <t:MiddleName>Middle</t:MiddleName>
                    <t:Nickname>Adina</t:Nickname>
                    <t:CompleteName>
                      <t:FirstName>Hagege</t:FirstName>
                      <t:MiddleName>Middle</t:MiddleName>
                      <t:LastName>Hagege</t:LastName>
                      <t:FullName>Hagege</t:FullName>
                      <t:Nickname>Adina</t:Nickname>
                    </t:CompleteName>
                    <t:Surname>Hagege</t:Surname>
                  </t:Contact>
              <t:Contact>
                <t:ItemId Id="AQMkAGEyYzQ" ChangeKey="EQAAABYAAA" />
                <t:ParentFolderId Id="AQMkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAuAAADxdu66sOO90WjgEbv6Ra2VAEAwmVnt/opXEiv3zVwB"+hrOAAAAyAAAAA=" 
                   ChangeKey="AQAAAA==" />
                <t:ItemClass>IPM.Contact</t:ItemClass>
                <t:Subject>New Subject?</t:Subject>
                <t:Sensitivity>Normal</t:Sensitivity>
                <t:DateTimeReceived>2009-10-13T17:27:53Z</t:DateTimeReceived>
                <t:Size>147</t:Size>
                <t:Importance>Normal</t:Importance>
                <t:IsSubmitted>false</t:IsSubmitted>
                <t:IsDraft>true</t:IsDraft>
                <t:IsFromMe>false</t:IsFromMe>
                <t:IsResend>false</t:IsResend>
                <t:IsUnmodified>false</t:IsUnmodified>
                <t:DateTimeSent>2009-10-13T17:27:53Z</t:DateTimeSent>
                <t:DateTimeCreated>2009-10-13T17:27:53Z</t:DateTimeCreated>
                <t:DisplayCc />
                <t:DisplayTo />
                <t:HasAttachments>false</t:HasAttachments>
                <t:Culture>en-US</t:Culture>
                <t:EffectiveRights>
                  <t:CreateAssociated>false</t:CreateAssociated>
                  <t:CreateContents>false</t:CreateContents>
                  <t:CreateHierarchy>false</t:CreateHierarchy>
                  <t:Delete>true</t:Delete>
                  <t:Modify>true</t:Modify>
                  <t:Read>true</t:Read>
                </t:EffectiveRights>
                <t:LastModifiedName>E14UserTwo</t:LastModifiedName>
                <t:LastModifiedTime>2009-10-13T17:27:53Z</t:LastModifiedTime>
                <t:IsAssociated>false</t:IsAssociated>
                <t:WebClientReadFormQueryString>
                  ?ae=Item&amp;a=Open&amp;t=IPM.
                  Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAAA
                  gAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZL5AAAR&amp;exvsurl=1</t:WebClientReadFormQuer
yString>
                  <t:WebClientEditFormQueryString>
                    ?ae=Item&amp;a=Open&amp;s=Draf
                    t&amp;t=IPM.Contact&amp;id=RgAAAADF27rqw473RaOARu%2fpFrZUBwDCZWe3%2bilcSK%2ffNXA
                    H6Gs4AAAAAAAgAADCZWe3%2bilcSK%2ffNXAH6Gs4AAAAAZL5AAAR&amp;exvsurl=1</t:WebClient
EditFormQueryString>
                    <t:ConversationId Id="AAQkAGEyYzQ2MzQ1LTg2MGEtNDkxMy1hZjE3LWNl
MmEzYTYxOWUzOQAQANQdjNmPALIE6YAJmOz4Qn4=" />
                    <t:FileAs />
                    <t:FileAsMapping>None</t:FileAsMapping>
                    <t:DisplayName>Hassall</t:DisplayName>
                    <t:GivenName>Hassall</t:GivenName>
                    <t:MiddleName>Middle</t:MiddleName>
                    <t:Nickname>Mark</t:Nickname>
                    <t:CompleteName>
                      <t:FirstName>Hassall</t:FirstName>
                      <t:MiddleName>Middle</t:MiddleName>
                      <t:LastName>Hassall</t:LastName>
                      <t:FullName>Hassall</t:FullName>
                      <t:Nickname>Mark</t:Nickname>
                    </t:CompleteName>
                    <t:Surname>Hassall</t:Surname>
                  </t:Contact>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

This example assumes that the ExchangeService object named service is correctly configured to connect to the user’s Client Access server.

Compiling the code

For information about compiling this code, see Getting started with the EWS Managed API 2.0.

Robust programming

  • Write appropriate error handling code for common search errors.

  • Review the client request XML that is sent to the Exchange server.

  • Review the server response XML that is sent from the Exchange server.

  • Set the service binding as shown in Setting the Exchange service URL by using the EWS Managed API 2.0. Do not hard code URLs because if mailboxes move, they might be serviced by a different Client Access server. If the client cannot connect to the service, retry setting the binding by using the AutodiscoverUrl(String) method.

  • Set the target Exchange Web Services schema version by setting the requestedServerVersion parameter of the ExchangeService constructor. For more information, see Versioning EWS requests by using the EWS Managed API 2.0.

Security

  • Use HTTP with SSL for all communication between client and server.

  • Always validate the server certificate that is used for establishing the SSL connections. For more information, see Validating X509 certificates by using the EWS Managed API 2.0.

  • Do not include user names and passwords in trace files.

  • Verify that Autodiscover lookups that use HTTP GET to find an endpoint always prompt for user confirmation; otherwise, they should be blocked.