HOWTO: GetFolder, FindItem, Restriction, GetItem
This is an attempt to extend my previous code sample Getting into a folder by path using EWS
With this code sample I have demonstrated HOWTO find items under a folder.
I have used Restriction to list down all the "IPM.Note" items falling under a specified date/time span.
class EWS_SAMPLE
{
static void Main(string[] args)
{
ExchangeServiceBinding esb = new ExchangeServiceBinding();
esb.Credentials = new System.Net.NetworkCredential("Username", "Password");
esb.Url = "https://server-name-here/EWS/Exchange.asmx";
BaseFolderType bft = GetFolderByPath(esb, "/Inbox/myFolder");
if (null == bft)
Console.WriteLine("Folder not found.");
else
{
Console.WriteLine("Folder Found: " + bft.DisplayName);
ItemType[] its = FindAllItems(esb, bft.FolderId.Id, DateTime.Parse("07/25/2007 00:00"), DateTime.Parse("07/30/2007 00:00"));
if (null == its)
return;
foreach (ItemType it in its)
{
MessageType mt;
mt = GetItem(esb, it.ItemId.Id) as MessageType;
if (null == mt)
Console.WriteLine("Item not found");
else
Console.WriteLine(mt.DateTimeSent + " >> " + mt.Subject + " >> " + mt.Sender.Item.EmailAddress);
}
}
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 ItemType GetItem(ExchangeServiceBinding esb, string szItemId)
{
if (null == esb || null == szItemId)
return null;
//specify the content that we want to retrieve, we are retrieving AllProperties
ItemResponseShapeType irst = new ItemResponseShapeType();
irst.BaseShape = DefaultShapeNamesType.AllProperties;
irst.IncludeMimeContent = true;
irst.IncludeMimeContentSpecified = true;
ItemIdType iit = new ItemIdType();
iit.Id = szItemId;
BaseItemIdType[] biit = new BaseItemIdType[1];
biit[0] = iit;
//get the item
GetItemType git = new GetItemType();
git.ItemShape = irst;
git.ItemIds = biit;
GetItemResponseType girt = esb.GetItem(git);
if (girt.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)
return ((ItemType)(((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0]));
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;
}
static public ItemType[] FindAllItems(ExchangeServiceBinding esb, string strFolderID, DateTime StartDate, DateTime EndDate)
{
if (null == esb || null == strFolderID || "" == strFolderID)
return null;
//get the inbox folder ID
FolderIdType[] fita = new FolderIdType[1];
fita[0] = new FolderIdType();
fita[0].Id = strFolderID;
//request AllProperties
PathToUnindexedFieldType[] ptufta = new PathToUnindexedFieldType[1];
ptufta[0] = new PathToUnindexedFieldType();
ptufta[0].FieldURI = UnindexedFieldURIType.itemItemClass;
ItemResponseShapeType irst = new ItemResponseShapeType();
irst.BaseShape = DefaultShapeNamesType.AllProperties;
irst.IncludeMimeContent = false;
irst.AdditionalProperties = ptufta;
//restrict the returned items to just items of a specific message class
PathToUnindexedFieldType MsgClassField = new
PathToUnindexedFieldType();
MsgClassField.FieldURI = UnindexedFieldURIType.itemItemClass;
ConstantValueType MsgClassToGet = new ConstantValueType();
MsgClassToGet.Value = "IPM.NOTE";
FieldURIOrConstantType MsgClassConstant = new
FieldURIOrConstantType();
MsgClassConstant.Item = MsgClassToGet;
IsEqualToType iett = new IsEqualToType();
iett.FieldURIOrConstant = MsgClassConstant;
iett.Item = MsgClassField;
//restrict the returned items greater than a specified date
PathToUnindexedFieldType StartDateReceivedField = new PathToUnindexedFieldType();
StartDateReceivedField.FieldURI = UnindexedFieldURIType.itemDateTimeReceived;
ConstantValueType StartDateReceivedToGet = new ConstantValueType();
StartDateReceivedToGet.Value = StartDate.ToUniversalTime().ToString();
FieldURIOrConstantType StartDateReceivedConstant = new FieldURIOrConstantType();
StartDateReceivedConstant.Item = StartDateReceivedToGet;
IsGreaterThanOrEqualToType igtett = new IsGreaterThanOrEqualToType();
igtett.FieldURIOrConstant = StartDateReceivedConstant;
igtett.Item = StartDateReceivedField;
//restrict the returned items less than a specified date
PathToUnindexedFieldType EndDateReceivedField = new PathToUnindexedFieldType();
EndDateReceivedField.FieldURI = UnindexedFieldURIType.itemDateTimeReceived;
ConstantValueType EndDateReceivedToGet = new ConstantValueType();
EndDateReceivedToGet.Value = EndDate.ToUniversalTime().ToString();
FieldURIOrConstantType EndDateReceivedConstant = new FieldURIOrConstantType();
EndDateReceivedConstant.Item = EndDateReceivedToGet;
IsLessThanOrEqualToType iltett = new IsLessThanOrEqualToType();
iltett.FieldURIOrConstant = EndDateReceivedConstant;
iltett.Item = EndDateReceivedField;
AndType at = new AndType();
at.Items = new SearchExpressionType[3];
at.Items[0] = igtett;
at.Items[1] = iltett;
//TODO: Uncomment the following line if you want to display only email items from folder
// If the following line is commented then all items would be returned from folder,
// for e.g. Reports, Appointment, Meeting Requests, Contacts etc.
//at.Items[2] = iett;
RestrictionType rt = new RestrictionType();
rt.Item = at;
//find the items
FindItemType fit = new FindItemType();
fit.ItemShape = irst;
fit.ParentFolderIds = fita;
fit.Restriction = rt;
FindItemResponseType firt = esb.FindItem(fit);
return
((ArrayOfRealItemsType)((FindItemResponseMessageType)firt.ResponseMessages
.Items[0]).RootFolder.Item).Items;
}
}
Comments
Anonymous
September 19, 2007
Very good!! Give me great help !Anonymous
April 16, 2008
Excellent example thanks a lot!!Anonymous
September 19, 2008
Thank you very much for this post. It was very helpful to me. I think I may have found two small bugs in the code. In the GetFolder function you have FolderQueryTraversalType.Deep specified for the search. I believe it should be FolderQueryTraversalType.Shallow. Also, when I changed this I wasn't finding anything off the root directory, so after a little digging I found that in the GetRootFolderId function you search for DistinguishedFolderIdNameType.root. I believe that should be DistinguishedFolderIdNameType.root. The way it was before, If I was searching for a folder and there were two with the same name under a particular parent, it was finding the wrong one. Once I changed these two things everything seemed to work fine. -JimAnonymous
September 19, 2008
Glad I could help. I agree with you about the bugs.Anonymous
September 19, 2008
Turns out my bug report had a bug in it. I meant to say it should have been DistinguishedFolderIdNameType.msgfolderroot. It really was very helpful I had a project to do and i've never worked with Exchange web services before. This really got me started. -JimAnonymous
January 08, 2009
hi.. first let me know ... how to add service.asmx to my project... I am struck with this.. Let u mail to this id pls : troy2.net@gmail.com thanksAnonymous
January 09, 2009
What version of VS are you on? If its 2005 then you can simply add a web reference to project but if its 2008 then you need to select add service reference & from there you select add web reference instead. Contact me via http://blogs.msdn.com/vikas/contact.aspx page if you have any further questionAnonymous
June 24, 2009
I tried this but, BaseFolderType bft = GetFolderByPath(esb, "/Inbox"); it jumps to "Folder not found". I need to get use your "GetAttachment" code, for that I need Item info.. Any other of getting that. (p.s. I don't have any folders inside inbox of a user, all are mails with attachments.) dananjaya@e-solutions.lkAnonymous
June 24, 2009
The comment has been removedAnonymous
August 05, 2009
Please send me the request/response XML from server. Contact me via email @ http://blogs.msdn.com/vikas/contact.aspxAnonymous
August 20, 2009
Thanks for the coding. But I am getting an error in the responsclass type as responeclasstype.error(it is supposed to be responseclasstype.success) if i try to read the mails within certain dates. ThanksAnonymous
August 20, 2009
@Seetha: Could you please share the XML generated by the request and response with me? Contact me via contact pageAnonymous
September 01, 2009
Hi, This is my first time i try to use Web Services and VS for that matter and i have a little problem. return ((ArrayOfRealItemsType)((FindItemResponseMessageType firt.ResponseMessages .Items[0]).RootFolder.Item).Items; } Is giving my an: "Object reference not set to an instance of an object" Any help with what should i do? I am using VS 2008 Thanx allready.Anonymous
October 11, 2009
I had the same problem too. return ((ArrayOfRealItemsType)((FindItemResponseMessageType firt.ResponseMessages .Items[0]).RootFolder.Item).Items; The issue is with the date range passed to the RestrictionType. I don't need to worry about a date range so changed it to the following to get it working. RestrictionType rt = new RestrictionType(); rt.Item = iett; Eugene.Anonymous
September 14, 2011
FYI, the DateTime restriction won't work like that in Exchange 2010. Everywhere you pass set the Value property of a ConstantValueType instance to dateTime.ToUniversalTime().ToString(), you would need to pass "yyyy-MM-ddTHH:mm:ssZ" to ToString(). That change will work with both Exchange 2007 and 2010. Hopefully this saves someone else some frustration later.Anonymous
October 01, 2015
Thank you very much Daniel Cormier. 4 years latter working with exchange 2010 et 2013 you saved me lot of time.