Introduction
In part 1, I discussed about the brief history of Exchange Server 2007 and a brief description of EWS with it’s special features. I’ll try to keep the article short and more focused.
In this part, I’ll explain how to read the messages from different folderand searching on it.
Here we can have two things.
- Reading all the mails for folders like Inbox, SentItems, Drafts etc. Here EWS provides us the facility for paging and sorting
- Searching can also be applied in these folders on some criteria
I’ll discuss both in this article.
Few points regarding reading mails for different folders
Here we use an API FindItem
provided by EWS which only returns 512 bytes of an item i. e. the returned object’s all properties can’t be populated although we can specify some properties that we want.
The key EWS functionalities are discussed here:
- Getting the count of the items in a specified folder
- Getting the count of the unread items in a specified folder
- Readings the Items in a specified folder with following attributes
- Sorting (Ascending or Descending) items: Based on some properties like subject, from etc.
- Index view: Means a specified number of items (for paging)
- Reading specific properties of Items
- Searching the Folders
- Single property searching
- Multiple property searching
For all this, we need the FolderID
of the folders folders like Inbox, SentItems, Drafts etc…So we need to call one other API for this like below:
public FolderIdType FindFolderID()
{
DistinguishedFolderIdType objSearchRootFolder = new DistinguishedFolderIdType();
objSearchRootFolder.Id = DistinguishedFolderIdNameType.msgfolderroot;
FindFolderType requestFindFolder = new FindFolderType();
requestFindFolder.Traversal = FolderQueryTraversalType.Deep;
requestFindFolder.ParentFolderIds = new DistinguishedFolderIdType[] { objSearchRootFolder };
requestFindFolder.FolderShape = new FolderResponseShapeType();
requestFindFolder.FolderShape.BaseShape = DefaultShapeNamesType.IdOnly;
requestFindFolder.Restriction = new RestrictionType();
#region Contains expression
ContainsExpressionType objContainsExpression = new ContainsExpressionType();
objContainsExpression.ContainmentMode = ContainmentModeType.FullString;
objContainsExpression.ContainmentModeSpecified = true;
objContainsExpression.ContainmentComparison = ContainmentComparisonType.Exact;
objContainsExpression.ContainmentComparisonSpecified = true;
PathToUnindexedFieldType objFieldFolderName = new PathToUnindexedFieldType();
objFieldFolderName.FieldURI = UnindexedFieldURIType.folderDisplayName;
objContainsExpression.Item = objFieldFolderName;
objContainsExpression.Constant = new ConstantValueType();
objContainsExpression.Constant.Value = "Inbox";
#endregion Contains expression
requestFindFolder.Restriction.Item = objContainsExpression;
FindFolderResponseType objFindFolderResponse =
_esb.FindFolder(requestFindFolder);
if (objFindFolderResponse.ResponseMessages.Items.Length == 0)
return null;
foreach (ResponseMessageType responseMsg in
objFindFolderResponse.ResponseMessages.Items)
{
if (responseMsg.ResponseClass == ResponseClassType.Success)
{
FindFolderResponseMessageType objFindResponse =
responseMsg as FindFolderResponseMessageType;
foreach (
BaseFolderType objFolderType in objFindResponse.RootFolder.Folders)
{
return objFolderType.FolderId;
}
}
}
return null;
}
Getting the Count of the Items in a Specified Folder
If the folder contains no Item, It'll return -1.
public int GetFolderItemsCount()
{
FindItemType findRequest = new FindItemType();
findRequest.ItemShape = new ItemResponseShapeType();
findRequest.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
BaseFolderIdType p_folder = FindFolderID();
findRequest.ParentFolderIds = new BaseFolderIdType[] { p_folder };
findRequest.Traversal = ItemQueryTraversalType.Shallow;
FindItemResponseType response = _esb.FindItem(findRequest);
FindItemResponseMessageType responseMessage =
response.ResponseMessages.Items[0]
as FindItemResponseMessageType;
if (responseMessage.ResponseCode != ResponseCodeType.NoError)
{
throw new Exception(responseMessage.MessageText);
}
else
{
if (responseMessage != null && responseMessage.RootFolder != null)
{
return responseMessage.RootFolder.TotalItemsInView;
}
else
{
return -1;
}
}
}
Getting the Count of the Unread Items in a Specified Folder
public int GetUnreadFolderItemsCount()
{
int unReadCount = -1;
FolderResponseShapeType properties = new FolderResponseShapeType();
PathToUnindexedFieldType ptuft = new PathToUnindexedFieldType();
ptuft.FieldURI = UnindexedFieldURIType.folderManagedFolderInformation;
PathToUnindexedFieldType[] ptufts = new PathToUnindexedFieldType[1] { ptuft };
properties.AdditionalProperties = ptufts;
properties.BaseShape = DefaultShapeNamesType.AllProperties;
BaseFolderIdType p_folder = FindFolderID();
GetFolderType request = new GetFolderType();
request.FolderIds = new BaseFolderIdType[1] { p_folder };
request.FolderShape = properties;
GetFolderResponseType response = _esb.GetFolder(request);
ArrayOfResponseMessagesType aormt = response.ResponseMessages;
ResponseMessageType[] rmta = aormt.Items;
foreach (ResponseMessageType rmt in rmta)
{
if (rmt.ResponseClass == ResponseClassType.Error)
{
throw new Exception(rmt.MessageText);
}
else
{
FolderInfoResponseMessageType firmt;
firmt = (rmt as FolderInfoResponseMessageType);
BaseFolderType[] folders = firmt.Folders;
foreach (BaseFolderType rfolder in folders)
{
if (rfolder is FolderType)
{
FolderType myFolder;
myFolder = (rfolder as FolderType);
if (myFolder.UnreadCountSpecified)
{
unReadCount = myFolder.UnreadCount;
}
}
}
}
}
return unReadCount;
}
Readings the Items in a Specified Folder
public List<messagetype> GetFolderItems()
{
FindItemType findRequest = new FindItemType();
findRequest.ItemShape = new ItemResponseShapeType();
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
itemProperties.BaseShape = DefaultShapeNamesType.Default;
findRequest.ItemShape = itemProperties;
Set the inbox as the parent search folder in search attachementRequest.
BaseFolderIdType p_folder = FindFolderID();
findRequest.ParentFolderIds = new BaseFolderIdType[] { p_folder };
findRequest.Traversal = ItemQueryTraversalType.Shallow;
FindItemResponseType response = _esb.FindItem(findRequest);
FindItemResponseMessageType responseMessage =
response.ResponseMessages.Items[0]
as FindItemResponseMessageType;
if (responseMessage.ResponseCode != ResponseCodeType.NoError)
{
throw new Exception(responseMessage.MessageText);
}
else
{
ArrayOfRealItemsType items = responseMessage.RootFolder.Item as
ArrayOfRealItemsType;
if (items.Items == null)
{
return null;
}
List<messagetype> result = new List<messagetype>(items.Items.Length);
foreach (MessageType item in items.Items)
{
result.Add(item);
}
return result;
}
}
For sorting, first we need to select on which field I want to sort, here I selected Subject:
FieldOrderType[] fieldsOrder = new FieldOrderType[1];
fieldsOrder[0] = new FieldOrderType();
PathToUnindexedFieldType pathSortField = new PathToUnindexedFieldType();
pathSortField.FieldURI = UnindexedFieldURIType.itemSubject;
fieldsOrder[0].Order = SortDirectionType.Descending;
findRequest.SortOrder = fieldsOrder;
For indexed view (i. e. if I want to bring only 10 items at a time from server) we can set set the max item returned and can set the startitem I'd like.
IndexedPageViewType indexedView = new IndexedPageViewType();
indexedView.BasePoint = IndexBasePointType.Beginning;
indexedView.MaxEntriesReturned = p_intMaxRec;
indexedView.MaxEntriesReturnedSpecified = true;
indexedView.Offset = p_intStartIdx;
findRequest.Item = indexedView;
Here, also if I want some special properties then I can do like below:
PathToUnindexedFieldType pathSentDateTime = new PathToUnindexedFieldType();
pathSentDateTime.FieldURI = UnindexedFieldURIType.itemDateTimeSent;
itemProperties.AdditionalProperties = new BasePathToElementType[] { pathSentDateTime;}
findRequest.ItemShape = itemProperties;
Searching the Folders
For searching any folder we need to to do the same as above for all those properties. We also need here one other object of class RestrictionType
as:
RestrictionType objRestrictionType = new RestrictionType();
In searching, we have two options:
- search on single property like subject or sentdatetime etc.
- search on multiple properties like subject and sentdatetime and etc.
For single property searching we need to create the object of OrType
as
OrType orType = new OrType();
Else for multiple
AndType andType = new AndType();
And another one object of type as ContainsExpressionType
Here ContainsRxpressionType
is used because if, let’s say, the subject is hello and we give the value just “hel” then it’ll search all the items in which the subject value contains “hel.”
ContainsExpressionType expressionType = null;
List<searchexpressiontype> searchExps = null;
Now for searching for subject
PathToUnindexedFieldType path.FieldURI = UnindexedFieldURIType.itemSubject;
expressionType = new ContainsExpressionType();
expressionType.Item = path;
expressionType.ContainmentMode = ContainmentModeType.Substring;
expressionType.ContainmentModeSpecified = true;
expressionType.ContainmentComparison =
ContainmentComparisonType.IgnoreCaseAndNonSpacingCharacters;
expressionType.ContainmentComparisonSpecified = true;
expressionType.Constant = new ConstantValueType();
expressionType.Constant.Value = “Hi”;
searchExps.Add(expressionType);
Similarly we can iterate for as many properies as we want:
Now for andType
andType.Items = searchExps.ToArray();
objRestrictionType.Item = andType;
for OrType
orType.Items = searchExps.ToArray();
objRestrictionType.Item = orType;
For this restriction type object we need to set in findrequest
as:
findRequest.Restriction = p_RestrictionType;
then it’ll search the folder according to the restriction.
I'll discuss in the next part, reading details of mail from different folders. Also, I'll try to cover the one of the main features of the EWS Extended property, which is very useful when we need some custom attributes for the every item.