Синхронизация папок с помощью EWS в Exchange
Узнайте, как использовать управляемый API EWS или EWS для получения списка папок или списка измененных папок для синхронизации клиента.
EWS в Exchange использует синхронизацию элементов и синхронизацию папок для синхронизации содержимого почтового ящика между клиентом и сервером. Синхронизация папок получает начальный список папок из корневой папки, а затем со временем получает изменения, внесенные в эти папки, а также новые папки.
Если вы выполняете синхронизацию папок с помощью управляемого API EWS, сначала получите начальный список папок в корневой папке с помощью метода ExchangeService.SyncFolderHierarchy . Затем вы обновляете значение параметра cSyncState во время последующих вызовов, чтобы получить список новых и измененных папок.
Чтобы выполнить синхронизацию папок с помощью EWS, необходимо запросить начальный список папок в корневой папке с помощью операции SyncFolderHierarchy , проанализировать ответ, а затем в будущем получить изменения в папках в корневой папке и проанализировать ответ. После получения клиентом списка исходных или измененных папок он выполняет обновления локально. Способ и время получения изменений в будущем зависит от шаблона структуры синхронизации , используемого приложением.
Получение списка всех папок или измененных папок с помощью управляемого API EWS
В следующем примере кода показано, как получить начальный список папок в корневой папке, а затем получить список изменений в папках в корневой папке, произошедших с момента предыдущей синхронизации. Во время первоначального вызова метода ExchangeService.SyncFolderHierarchy задайте для параметра cSyncState значение NULL. После завершения метода сохраните значение cSyncState локально, чтобы использовать его в следующем вызове метода SyncFolderHierarchy . Как при первоначальном вызове, так и в последующих вызовах папки извлекаются пакетами из десяти, используя последовательные вызовы метода SyncFolderHierarchy , пока не останется никаких изменений. В этом примере параметру propertySet присваивается значение IdOnly, чтобы уменьшить количество вызовов к базе данных Exchange, что является оптимальным вариантом синхронизации. В этом примере предполагается, что служба является допустимой привязкой объекта ExchangeService , а cSyncState представляет состояние синхронизации, возвращенное предыдущим вызовом 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;
После получения списка новых или измененных папок на сервере создайте или обновите папки на клиенте.
Получение начального списка папок с помощью EWS
В следующем примере показан XML-запрос для получения начальной иерархии папок с помощью операции SyncFolderHierarchy . Это также XML-запрос, который управляемый API EWS отправляет при получении списка исходных папок с помощью метода SyncFolderHierarchy. Элемент SyncState операции SyncFolderHierarchy не включен, так как это начальная синхронизация. В этом примере элементу BaseShape присваивается значение IdOnly , чтобы уменьшить количество вызовов к базе данных Exchange, что является оптимальным вариантом синхронизации.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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>
В следующем примере показан XML-ответ, возвращаемый сервером после обработки запроса на операцию SyncFolderHierarchy . Первоначальный ответ включает элементы Create для всех папок, так как все папки считаются новыми во время начальной синхронизации. Значения некоторых атрибутов и элементов сокращены для удобства чтения, а некоторые блоки элементов Create были удалены для краткости.
<?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="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://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="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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>
После получения списка новых папок на сервере создайте папки на клиенте.
Получение изменений с момента последней синхронизации с помощью EWS
В следующем примере показан XML-запрос для получения списка изменений папок в корневой папке с помощью операции SyncFolderHierarchy . Это также XML-запрос, который управляемый API EWS отправляет при получении списка изменений в корневой папке. В этом примере задается значение элемента SyncState , возвращаемое в предыдущем ответе. В целях демонстрации в этом примере для элемента BaseShape задается значение AllProperties , а не IdOnly , чтобы отобразить возвращенные дополнительные свойства. Рекомендуется установить для элемента BaseShape значение IdOnly. Значение SyncState сокращено для удобства чтения.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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>
В следующем примере показан XML-ответ, возвращаемый сервером после обработки запроса на операцию SyncFolderHierarchy от клиента. Этот ответ указывает, что одна папка была обновлена, одна папка создана, а одна папка была удалена с момента предыдущей синхронизации. Значение элемента SyncState , атрибутов Id и ChangeKey сокращено для удобства чтения.
Помните, что запрос включал AllPropertiesBaseShape. Это только для демонстрационных целей. Рекомендуется задать для элемента BaseShape значение IdOnly в рабочей среде.
<?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="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://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="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://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>
Обновление клиента
Если вы используете управляемый API EWS, после получения списка новых или измененных папок используйте метод Folder.Load , чтобы получить свойства новых или измененных элементов, сравнить свойства с локальными значениями и обновить или создать папки на клиенте.
Если вы используете EWS, используйте операцию GetFolder , чтобы получить свойства новых или измененных папок, а также обновить или создать папки на клиенте.