Trabalhar com pastas ocultas usando o EWS no Exchange
Saiba como ocultar uma pasta e localizar pastas ocultas usando a API Gerenciada do EWS ou o EWS no Exchange.
Com uma exceção, as pastas na raiz de uma caixa de correio do Exchange (a subtree não IPM) estão ocultas do usuário. Por outro lado, todas as pastas no MsgFolderRoot (a sub-árvore IPM) estão visíveis para o usuário. Então, como você oculta uma pasta sob o MsgFolderRoot? Não é tão complicado – se resume a apenas uma propriedade, a propriedade estendida PidTagAttributeHidden (0x10F4000B). Quando essa propriedade é definida como true, o Outlook ou outro cliente que usa a propriedade para determinar a visibilidade da pasta ocultará a pasta do modo de exibição do usuário. Como esta é uma propriedade estendida, é mais complexo usar do que sua propriedade de pasta média, portanto, este artigo irá orientá-lo através dos cenários principais.
Tabela 1. Métodos de API Gerenciada do EWS e operações EWS para trabalhar com pastas ocultas
Tarefa | Método da API Gerenciada do EWS | Operação do EWS |
---|---|---|
Ocultar uma pasta |
Folder.Bind seguido por Folder.Update |
GetFolder seguido por UpdateFolder |
Localizar pastas ocultas |
FindFolders |
FindFolder |
Você está se perguntando qual é a única exceção: ou seja, qual pasta na raiz é visível para os usuários? É a pasta Finder (também conhecida como o valor de enumeração SearchFoldersWellKnownFolder ou o valor do elemento DistinguishedFolderId dos searchfolders), que contém as pastas de pesquisa dos usuários. As pastas de pesquisa criadas na pasta Finder estão visíveis para os usuários do Outlook. Se você precisar criar uma pasta de pesquisa que não esteja visível para os usuários, mova-a para baixo da pasta raiz para escondê-la. Ao contrário de outras pastas, definir a propriedade PidTagAttributeHiddencomo true não ocultará uma pasta de pesquisa na pasta Finder.
Ocultar uma pasta usando a API Gerenciada do EWS
Você pode tornar uma pasta existente uma pasta oculta alterando a propriedade estendida PidTagAttributeHidden para true. Primeiro, crie uma definição de propriedade estendida para a propriedade. Em seguida, use o método Bind para acessar a pasta e atualize o valor da propriedade PidTagAttributeHidden para true e use o método Update para salvar as alterações.
Este exemplo pressupõe que o serviço seja um objeto ExchangeService válido para o proprietário da caixa de correio, que o usuário foi autenticado em um servidor exchange e que folderId é um Folder.Id válido que identifica a pasta a ser ocultada.
private static void MakeHidden(FolderId folderId, ExchangeService service)
{
// Create an extended property definition for the PidTagAttributeHidden property.
ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
PropertySet propSet = new PropertySet(isHiddenProp);
// Bind to a folder and retrieve the PidTagAttributeHidden property.
Folder folder = Folder.Bind(service, folderId, propSet);
// Set the PidTagAttributeHidden property to true.
folder.SetExtendedProperty(isHiddenProp, true);
// Save the changes.
folder.Update();
}
Ocultar uma pasta usando o EWS
Você pode usar o EWS para tornar uma pasta existente uma pasta oculta alterando a propriedade estendida PidTagAttributeHidden para true. Primeiro, use a operação GetFolder para acessar a pasta e recupere a propriedade PidTagAttributeHidden incluindo o elemento ExtendedFieldURI e definindo o valor PropertyTag como 4340 e o valor PropertyType como Boolean.
Essa também é a solicitação XML que a API Gerenciada do EWS envia quando você usa o método Bind para obter uma pasta antes de torná-la uma pasta oculta.
O valor FolderId é abreviado para legibilidade.
<?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="Exchange2007_SP1" />
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
</t:AdditionalProperties>
</m:FolderShape>
<m:FolderIds>
<t:FolderId Id="IQywAAAA==" />
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
O servidor responde à solicitação GetFolder com uma mensagem GetFolderResponse que inclui um valor de elemento ResponseCode de NoError, que indica que a pasta foi recuperada com êxito. A resposta também inclui um valor para o ExtendedProperty. Neste exemplo, o Valor é definido como false, o que significa que a pasta não está oculta no momento.
<?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="898"
MinorBuildNumber="23"
Version="V2_10"
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:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAABED" />
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>false</t:Value>
</t:ExtendedProperty>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
Para alterar o valor do ExtendedProperty para true, use a operação UpdateFolder . Inclua os elementos ExtendedProperty, ExtendedFieldURI e Value para a propriedade estendida PidTagAttributeHidden e defina o elemento Value como true para ocultar a pasta.
Essa também é a solicitação XML que a API Gerenciada do EWS envia quando você usa o método Update para atualizar uma pasta para torná-la uma pasta oculta.
<?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="Exchange2007_SP1" />
</soap:Header>
<soap:Body>
<m:UpdateFolder>
<m:FolderChanges>
<t:FolderChange>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAABED" />
<t:Updates>
<t:SetFolderField>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:Folder>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
</t:SetFolderField>
</t:Updates>
</t:FolderChange>
</m:FolderChanges>
</m:UpdateFolder>
</soap:Body>
</soap:Envelope>
O servidor responde à solicitação UpdateFolder com uma mensagem UpdateFolderResponse que inclui um valor de elemento ResponseCode do NoError, que indica que a pasta foi atualizada com êxito e agora está oculta.
Localizar todas as pastas ocultas usando a API Gerenciada do EWS
Você pode encontrar todas as pastas ocultas em uma pasta pai criando uma definição de propriedade estendida para a propriedade estendida PidTagAttributeHidden e, em seguida, usando o método FindFolders para encontrar pastas com um valor PidTagAttributeHidden definido como true. Este exemplo usa o MsgFolderRoot, também conhecido como Top of Information Store ou IPM Subtree, como a pasta pai a ser pesquisada.
Este exemplo pressupõe que o serviço seja um objeto ExchangeService válido para o proprietário da caixa de correio e que o usuário tenha sido autenticado em um servidor do Exchange.
private static void FindHiddenFolders(ExchangeService service)
{
// Create an extended property definition for the PidTagAttributeHidden property.
ExtendedPropertyDefinition isHiddenProp = new ExtendedPropertyDefinition(0x10f4, MapiPropertyType.Boolean);
// Create a folder view to retrieve up to 100 folders and
// retrieve only the PidTagAttributeHidden and the display name.
FolderView folderView = new FolderView(100);
folderView.PropertySet = new PropertySet(isHiddenProp, FolderSchema.DisplayName);
// Indicate a Traversal value of Deep, so that all subfolders are retrieved.
folderView.Traversal = FolderTraversal.Deep;
// Find all hidden folders under the MsgFolderRoot.
// This call results in a FindFolder call to EWS.
FindFoldersResults findFolder = service.FindFolders(WellKnownFolderName.MsgFolderRoot,
new SearchFilter.IsEqualTo(isHiddenProp, true), folderView);
// Display the folder ID and display name of each hidden folder.
foreach (Folder folder in findFolder)
{
Console.WriteLine("FolderId: {0}", folder.Id);
Console.WriteLine("DisplayName: {0}", folder.DisplayName);
Console.WriteLine("\r\n");
}
}
Localizar todas as pastas ocultas usando o EWS
Você pode usar o EWS para encontrar todas as pastas ocultas em uma pasta existente chamando a operação FindFolder e procurando pastas cuja propriedade estendida PidTagAttributeHidden está definida como true. Para fazer isso, inclua uma RestriçãoIsEqualTo que pesquisa o elemento ExtendedFieldURI para a propriedade PidTagAttributeHidden ( valor PropertyTag para 4243 e o valor PropertyType para Boolean), conforme mostrado na solicitação a seguir. Este exemplo usa o MsgFolderRoot, também conhecido como Top of Information Store ou IPM Subtree, como a pasta pai a ser pesquisada.
Essa também é a solicitação XML que a API Gerenciada do EWS envia quando você usa o método FindFolders para encontrar todas as pastas ocultas.
<?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="Exchange2007_SP1" />
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="Central Standard Time" />
</t:TimeZoneContext>
</soap:Header>
<soap:Body>
<m:FindFolder Traversal="Deep">
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:FieldURI FieldURI="folder:DisplayName" />
</t:AdditionalProperties>
</m:FolderShape>
<m:IndexedPageFolderView MaxEntriesReturned="100"
Offset="0"
BasePoint="Beginning" />
<m:Restriction>
<t:IsEqualTo>
<t:ExtendedFieldURI PropertyTag="4340"
PropertyType="Boolean" />
<t:FieldURIOrConstant>
<t:Constant Value="true" />
</t:FieldURIOrConstant>
</t:IsEqualTo>
</m:Restriction>
<m:ParentFolderIds>
<t:DistinguishedFolderId Id="msgfolderroot" />
</m:ParentFolderIds>
</m:FindFolder>
</soap:Body>
</soap:Envelope>
O servidor responde à solicitação FindFolder com uma mensagem FindFolderResponse que inclui um valor de elemento ResponseCode de NoError, o que indica que a pesquisa de pastas foi bem-sucedida, bem como todas as pastas ocultas na pasta de mensagem raiz.
Os valores FolderId são abreviados para legibilidade.
<?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="898"
MinorBuildNumber="23"
Version="V2_10"
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:FindFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:FindFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:RootFolder IndexedPagingOffset="6"
TotalItemsInView="6"
IncludesLastItemInRange="true">
<t:Folders>
<t:ContactsFolder>
<t:FolderId Id="IBHgAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACz" />
<t:DisplayName>{06967759-274D-40B2-A3EB-D7F9E73727D7}</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBHwAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAAC7" />
<t:DisplayName>{A9E2BC46-B3A0-4243-B315-60D991004455}</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBIQAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAADO" />
<t:DisplayName>GAL Contacts</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:ContactsFolder>
<t:FolderId Id="IBHQAAAA=="
ChangeKey="AwAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACa" />
<t:DisplayName>Recipient Cache</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:ContactsFolder>
<t:Folder>
<t:FolderId Id="HAAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAAAACS" />
<t:DisplayName>Conversation Action Settings</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
<t:Folder>
<t:FolderId Id="IQywAAAA=="
ChangeKey="AQAAABYAAAD32nSTjepyT63rYH17n9THAAAeZIBf" />
<t:DisplayName>TestFolder</t:DisplayName>
<t:ExtendedProperty>
<t:ExtendedFieldURI PropertyTag="0x10f4"
PropertyType="Boolean" />
<t:Value>true</t:Value>
</t:ExtendedProperty>
</t:Folder>
</t:Folders>
</m:RootFolder>
</m:FindFolderResponseMessage>
</m:ResponseMessages>
</m:FindFolderResponse>
</s:Body>
</s:Envelope>
Depois de ter pastas ocultas ou não ocultas, talvez você queira obter a hierarquia de pastas ou sincronizar a hierarquia de pastas. Os exemplos que mostram como obter uma hierarquia de pasta usando a API Gerenciada do EWS ou obter uma hierarquia de pasta usando o EWS também indicam quais pastas na hierarquia estão ocultas.