Sincronizar pastas usando o EWS no Exchange

Descubra como usar a API Gerenciada do EWS ou o EWS para obter uma lista de pastas ou uma lista de pastas que foram alteradas para sincronizar seu cliente.

O EWS no Exchange usa a sincronização de itens e a sincronização de pastas para sincronizar o conteúdo da caixa de correio entre o cliente e o servidor. A sincronização de pastas obtém a lista inicial de pastas de uma pasta raiz e, ao longo do tempo, obtém alterações feitas nessas pastas e obtém novas pastas também.

Se você estiver executando a sincronização de pastas usando a API Gerenciada do EWS, primeiro obterá a lista inicial de pastas na pasta raiz usando o método ExchangeService.SyncFolderHierarchy . Em seguida, você atualiza o valor do parâmetro cSyncState durante chamadas subsequentes para obter a lista de pastas novas e alteradas.

Para executar a sincronização de pastas usando o EWS, você solicita a lista inicial de pastas na pasta raiz usando a operação SyncFolderHierarchy , analisa a resposta e, em algum momento no futuro, obtém as alterações nas pastas na raiz e analisa a resposta. Depois que o cliente recebe a lista de pastas iniciais ou alteradas, ele faz atualizações localmente. Como e quando você recupera alterações no futuro depende do padrão de design de sincronização que seu aplicativo está usando.

Obter a lista de todas as pastas ou pastas alteradas usando a API Gerenciada do EWS

O exemplo de código a seguir mostra como obter uma lista inicial de pastas em uma pasta raiz e, em seguida, obter uma lista de alterações em pastas na pasta raiz que ocorreram desde a sincronização anterior. Durante a chamada inicial para o método ExchangeService.SyncFolderHierarchy , defina o valor cSyncState como nulo. Quando o método for concluído, salve o valor cSyncState localmente para usar na próxima chamada de método SyncFolderHierarchy . Na chamada inicial e nas chamadas subsequentes, as pastas são recuperadas em lotes de dez, usando chamadas sucessivas para o método SyncFolderHierarchy , até que não haja mais alterações. Este exemplo define o parâmetro propertySet como IdOnly para reduzir as chamadas para o banco de dados exchange, que é uma prática recomendada de sincronização. Neste exemplo, assumimos que o serviço é uma associação válida de objeto ExchangeService e que cSyncState representa o estado de sincronização que foi retornado por uma chamada anterior para SyncFolderHierarchy.

// Get a list of all folders in the mailbox by calling SyncFolderHierarchy.
// The folderId parameter must be set to the root folder to synchronize. 
// The propertySet parameter is set to IdOnly to reduce calls to the Exchange database
// because any additional properties result in additional calls to the Exchange database. 
// The syncState parameter is set to cSyncState, which should be null in the initial call, 
// and should be set to the sync state returned by the previous SyncFolderHierarchy call 
// in subsequent calls.
ChangeCollection<FolderChange> fcc = service.SyncFolderHierarchy(new FolderId(WellKnownFolderName.Root), PropertySet.IdOnly, cSyncState);
// If the count of changes is zero, there are no changes to synchronize.
if (fcc.Count == 0)
{
    Console.WriteLine("There are no folders to synchronize.");
}
// Otherwise, write all the changes included in the response 
// to the console. 
// For the initial synchronization, all the changes will be of type
// ChangeType.Create.
else
{
    foreach (FolderChange fc in fcc)
    {
        Console.WriteLine("ChangeType: " + fc.ChangeType.ToString());
        Console.WriteLine("FolderId: " + fc.FolderId);
        Console.WriteLine("===========");
    }
}
// Save the sync state for use in future SyncFolderItems requests.
// The sync state is used by the server to determine what changes to report
// to the client.
string fSyncState = fcc.SyncState;

Depois de recuperar a lista de pastas novas ou alteradas no servidor, crie ou atualize as pastas no cliente.

Obter a lista inicial de pastas usando o EWS

O exemplo a seguir mostra uma solicitação XML para obter a hierarquia de pasta inicial usando a operação SyncFolderHierarchy . Essa também é a solicitação XML que a API Gerenciada do EWS envia ao recuperar a lista de pastas iniciais usando o método SyncFolderHierarchy. O elemento SyncState da operação SyncFolderHierarchy não está incluído porque essa é a sincronização inicial. Este exemplo define o elemento BaseShape como IdOnly para reduzir as chamadas para o banco de dados exchange, que é uma prática recomendada de sincronização.

<?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="Exchange2013" />
  </soap:Header>
  <soap:Body>
    <m:SyncFolderHierarchy>
      <m:FolderShape>
        <t:BaseShape>IdOnly</t:BaseShape>
      </m:FolderShape>
      <m:SyncFolderId>
        <t:DistinguishedFolderId Id="root" />
      </m:SyncFolderId>
    </m:SyncFolderHierarchy>
  </soap:Body>
</soap:Envelope>

O exemplo a seguir mostra a resposta XML retornada pelo servidor depois que ele processa a solicitação de operação SyncFolderHierarchy . A resposta inicial inclui Criar elementos para todas as pastas porque todas as pastas são consideradas novas durante uma sincronização inicial. Os valores de alguns atributos e elementos foram abreviados para legibilidade e alguns blocos de elemento Create foram removidos para brevidade.

<?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="785"
                         MinorBuildNumber="6"
                         Version="V2_6"
                         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:SyncFolderHierarchyResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                                   xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:SyncFolderHierarchyResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:SyncState>H4sIAA==</m:SyncState>
          <m:IncludesLastFolderInRange>true</m:IncludesLastFolderInRange>
          <m:Changes>
            <t:Create>
              <t:Folder>
                <t:FolderId Id="AAMkADM="
                            ChangeKey="AQAAABYA"/>
              </t:Folder>
            </t:Create>
            <t:Create>
              <t:Folder>
                <t:FolderId Id="AAMkADMzM="
                            ChangeKey="AQAAABY"/>
              </t:Folder>
            </t:Create>
            <t:Create>
              <t:Folder>
                <t:FolderId Id="AAMkAD/AAA="
                            ChangeKey="AQAAABYA"/>
              </t:Folder>
            </t:Create>
            <t:Create>
              <t:Folder>
                <t:FolderId Id="AAMkADBh="
                            ChangeKey="AQAAABYA"/>
              </t:Folder>
            </t:Create>
            ...
          </m:Changes>
        </m:SyncFolderHierarchyResponseMessage>
      </m:ResponseMessages>
    </m:SyncFolderHierarchyResponse>
  </s:Body>
</s:Envelope>

Depois de recuperar a lista de novas pastas no servidor, crie as pastas no cliente.

Obter as alterações desde a última sincronização usando o EWS

O exemplo a seguir mostra a solicitação XML para obter a lista de alterações em pastas na pasta raiz usando a operação SyncFolderHierarchy . Essa também é a solicitação XML que a API Gerenciada do EWS envia ao recuperar a lista de alterações na pasta raiz. Este exemplo define o valor do elemento SyncState como o valor retornado na resposta anterior. E para fins de demonstração, este exemplo define o elemento BaseShape como AllProperties em vez de IdOnly para mostrar as propriedades adicionais retornadas. Definir o elemento BaseShape como IdOnly é uma prática recomendada de sincronização. O valor do SyncState foi abreviado para legibilidade.

<?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="Exchange2013" />
  </soap:Header>
  <soap:Body>
    <m:SyncFolderHierarchy>
      <m:FolderShape>
        <t:BaseShape>AllProperties</t:BaseShape>
      </m:FolderShape>
      <m:SyncFolderId>
        <t:DistinguishedFolderId Id="root" />
      </m:SyncFolderId>
      <m:SyncState>H4sIAA==</m:SyncState>
    </m:SyncFolderHierarchy>
  </soap:Body>
</soap:Envelope>

O exemplo a seguir mostra a resposta XML retornada pelo servidor depois que ele processa a solicitação de operação SyncFolderHierarchy do cliente. Essa resposta indica que uma pasta foi atualizada, uma pasta foi criada e uma pasta foi excluída desde a sincronização anterior. O valor dos atributos SyncState , Id e ChangeKey foi abreviado para legibilidade.

Lembre-se de que a solicitação incluiu o AllPropertiesBaseShape. Isso é apenas para fins de demonstração. Recomendamos que você defina o elemento BaseShape como IdOnly em produção.

<?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="745" MinorBuildNumber="21" Version="V2_3" 
           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:SyncFolderHierarchyResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
            xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:SyncFolderHierarchyResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:SyncState>H4sIAAA</m:SyncState>
          <m:IncludesLastFolderInRange>true</m:IncludesLastFolderInRange>
          <m:Changes>
            <t:Update>
              <t:Folder>
                <t:FolderId Id="AAMkADM=" ChangeKey="AQAAABY" />
                <t:ParentFolderId Id="AQMkADMzADI1==" ChangeKey="AQAAAA==" />
                <t:FolderClass>IPF.Note</t:FolderClass>
                <t:DisplayName>Meeting Notes</t:DisplayName>
                <t:TotalCount>3</t:TotalCount>
                <t:ChildFolderCount>0</t:ChildFolderCount>
                <t:EffectiveRights>
                  <t:CreateAssociated>true</t:CreateAssociated>
                  <t:CreateContents>true</t:CreateContents>
                  <t:CreateHierarchy>true</t:CreateHierarchy>
                  <t:Delete>true</t:Delete>
                  <t:Modify>true</t:Modify>
                  <t:Read>true</t:Read>
                  <t:ViewPrivateItems>true</t:ViewPrivateItems>
                </t:EffectiveRights>
                <t:UnreadCount>0</t:UnreadCount>
              </t:Folder>
            </t:Update>
            <t:Create>
              <t:Folder>
                <t:FolderId Id="AAMkADMzM=" ChangeKey="AQAAABYAA" />
                <t:ParentFolderId Id="AQMkO67A==" ChangeKey="AQAAAA==" />
                <t:FolderClass>IPF.Note</t:FolderClass>
                <t:DisplayName>Schedules</t:DisplayName>
                <t:TotalCount>0</t:TotalCount>
                <t:ChildFolderCount>0</t:ChildFolderCount>
                <t:EffectiveRights>
                  <t:CreateAssociated>true</t:CreateAssociated>
                  <t:CreateContents>true</t:CreateContents>
                  <t:CreateHierarchy>true</t:CreateHierarchy>
                  <t:Delete>true</t:Delete>
                  <t:Modify>true</t:Modify>
                  <t:Read>true</t:Read>
                  <t:ViewPrivateItems>true</t:ViewPrivateItems>
                </t:EffectiveRights>
                <t:UnreadCount>0</t:UnreadCount>
              </t:Folder>
            </t:Create>
            <t:Delete>
              <t:FolderId Id="AAMkAD/AAA=" ChangeKey="AQAAAA==" />
            </t:Delete>
          </m:Changes>
        </m:SyncFolderHierarchyResponseMessage>
      </m:ResponseMessages>
    </m:SyncFolderHierarchyResponse>
  </s:Body>
</s:Envelope>

Atualizar o cliente

Se você estiver usando a API Gerenciada do EWS, depois de obter a lista de pastas novas ou alteradas, use o método Folder.Load para obter propriedades nos itens novos ou alterados, compare as propriedades com os valores locais e atualize ou crie as pastas no cliente.

Se você estiver usando o EWS, use a operação GetFolder para obter propriedades nas pastas novas ou alteradas e atualizar ou criar as pastas no cliente.

Confira também