Exchange Web Service is very powerful but everything has some limitations.
I've been struggling with one limitation that you cannot access any folder in Mailbox using its path like
/Inbox/MyFolder1/MyAnotherFolder/ThisIsTheFolderIWant
Client is not aware of the folder hierarchy on server side so you cannot access any folder directly, you need to create your own mechanism for that.
I am sharing the sample code I have created to Traverse down to the Folder path one by one and finally return the last folder.
Approach
- Suppose you want to get into “/Inbox/First/Second/Final” folder
- Get root folder’s ID
- Find Inbox using root folder’s ID
- Find First using Inbox folder’s ID
- and so on till Final folder
- Remember you should call FindFolder with FullString ContainmentModeType to get the desired result, otherwise you might get wrong folder
Code
Note: I have tested this code on Exchange 2007 RTM with Visual Studio 2005 , and it should work fine
class Program
{
static void Main(string[] args)
{
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new System.Net.NetworkCredential("UserName", "Password");
esb.Url = "https://YourExchangeServerHere/ews/exchange.asmx";
BaseFolderType bft = GetFolderByPath(esb, "/Inbox/Folder1/Folder2/Folder3/FinalFolder");
if (null == bft)
Console.WriteLine("Folder not found.");
else
Console.WriteLine("Folder Found: " + bft.DisplayName);
return;
}
static public BaseFolderType GetFolderByPath(ExchangeServiceBinding esb, string szFolderPath)
{
if (null == szFolderPath)
return null;
if (szFolderPath.IndexOf("/") == -1)
return null;
if (szFolderPath.Substring(0, 1).CompareTo("/") == 0)
szFolderPath = szFolderPath.Substring(1);
string[] Path = szFolderPath.Split('/');
string szParentFolderId = null;
BaseFolderType bft = null;
for (int i = 0; i < Path.GetLength(0); i++)
{
if (null == szParentFolderId)
szParentFolderId = GetRootFolderId(esb);
bft = GetFolder(esb, szParentFolderId, Path[i]);
if (null == bft)
return null;
else
szParentFolderId = bft.FolderId.Id;
}
return bft;
}
static public BaseFolderType GetFolder(ExchangeServiceBinding esb, string szParentFolderId, string szFolderName)
{
if (null == esb || null == szFolderName)
return null;
//get the root folder ID
FolderIdType[] fit = new FolderIdType[1];
fit[0] = new FolderIdType();
fit[0].Id = szParentFolderId;
//set the props that we want to retrieve
FolderResponseShapeType frst = new FolderResponseShapeType();
frst.BaseShape = DefaultShapeNamesType.AllProperties;
//restrict the search on the folder name
PathToUnindexedFieldType ftFolderName = new
PathToUnindexedFieldType();
ftFolderName.FieldURI = UnindexedFieldURIType.folderDisplayName;
ConstantValueType cvt = new ConstantValueType();
cvt.Value = szFolderName;
FieldURIOrConstantType ctFolderName = new FieldURIOrConstantType();
ctFolderName.Item = cvt;
ContainsExpressionType cet = new ContainsExpressionType();
cet.Constant = cvt;
cet.Item = ftFolderName;
cet.ContainmentComparison = ContainmentComparisonType.IgnoreCase;
cet.ContainmentComparisonSpecified = true;
cet.ContainmentMode = ContainmentModeType.FullString;
cet.ContainmentModeSpecified = true;
RestrictionType rt = new RestrictionType();
rt.Item = cet;
//find the folder
FindFolderType fft = new FindFolderType();
fft.Traversal = FolderQueryTraversalType.Deep;
fft.ParentFolderIds = fit;
fft.FolderShape = frst;
fft.Restriction = rt;
FindFolderResponseType ffrt = esb.FindFolder(fft);
ResponseMessageType rmt = ((ResponseMessageType)ffrt.ResponseMessages.Items[0]);
if (rmt.ResponseClass == ResponseClassType.Success)
{
BaseFolderType[] bfts = ((FindFolderResponseMessageType)ffrt.ResponseMessages.Items[0]).RootFolder.Folders;
if (bfts.GetLength(0) > 0)
return bfts[0];
else
return null;
}
else
return null;
}
static public string GetRootFolderId(ExchangeServiceBinding esb)
{
if (null == esb)
return null;
DistinguishedFolderIdType[] dfit = new DistinguishedFolderIdType[1];
//get the root folder ID
dfit[0] = new DistinguishedFolderIdType();
dfit[0].Id = DistinguishedFolderIdNameType.root;
//set the props that we want to retrieve
FolderResponseShapeType frst = new FolderResponseShapeType();
frst.BaseShape = DefaultShapeNamesType.AllProperties;
//get the folder
GetFolderType gftRoot = new GetFolderType();
gftRoot.FolderIds = dfit;
gftRoot.FolderShape = frst;
GetFolderResponseType gfrt = esb.GetFolder(gftRoot);
FolderInfoResponseMessageType firmt = ((FolderInfoResponseMessageType)gfrt.ResponseMessages.Items[0]);
if (firmt.ResponseClass == ResponseClassType.Success)
return ((FolderInfoResponseMessageType)gfrt.ResponseMessages.Items[0]).Folders[0].FolderId.Id;
else
return null;
}
}
Comments
Anonymous
July 26, 2007
This is an attempt to extend my previous code sample Getting into a folder by path using EWS With thisAnonymous
July 26, 2007
This is an attempt to extend my previous code sample Getting into a folder by path using EWS With thisAnonymous
October 28, 2008
Great POST!!!! Big thanx for helping us with your code. One question, what would I have to change if I want to find a a PUBLIC folderAnonymous
October 31, 2008
The comment has been removedAnonymous
March 06, 2009
Do you know how to get the mail enabled public folder's email address(es) after I get there? Thanks, RudiAnonymous
February 05, 2010
Do you know the root path of a public folder? If I have a test2010 folder would the path be "/test2010" or /Public/Test2010"? I tried both and it did not work. The Inbox code worked great! I have the ExchangeVersionType set to Exchange2010.