Hobby Chef
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; } }
Very good!!
Give me great help !
Excellent example thanks a lot!!
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.
-Jim
Glad I could help. I agree with you about the bugs.
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.
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
thanks
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 question
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.lk
Following line returns only zero objects...
BaseFolderType[] bfts = ((FindFolderResponseMessageType)ffrt.ResponseMessages.Items[0]).RootFolder.Folders;
Where it fails and returns 'null'
Please send me the request/response XML from server. Contact me via email @ http://blogs.msdn.com/vikas/contact.aspx
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.
Thanks
@Seetha: Could you please share the XML generated by the request and response with me? Contact me via contact page
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.
I had the same problem too.
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.
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.