Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / C#
Article

Programming With Exchange Server 2007 (EWS) - Part 2

Rate me:
Please Sign up or sign in to vote.
4.59/5 (19 votes)
14 Nov 2008CPOL3 min read 122K   44   21
This article is the second part of the series on EWS which explores Exchange Web Services

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:

C#
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;

            //Search filter definition
            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.

C#
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;

            // Perform the inbox search
            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

C#
public int GetUnreadFolderItemsCount()
        {
            int unReadCount = -1;
            // Identify the folder properties to return.
            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;

            // Form the get folder request.
            BaseFolderIdType p_folder = FindFolderID();

      GetFolderType request = new GetFolderType();
            request.FolderIds = new BaseFolderIdType[1] { p_folder };
            request.FolderShape = properties;

            // Send the request and get the response.
            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();
            // Use the Default shape for the response.            
            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;


            // Perform the inbox search
            FindItemResponseType response = _esb.FindItem(findRequest);
            FindItemResponseMessageType responseMessage =
                response.ResponseMessages.Items[0]
                    as FindItemResponseMessageType;
            if (responseMessage.ResponseCode != ResponseCodeType.NoError)
            {
                throw new Exception(responseMessage.MessageText);
            }
            else
            {
                // Set the next index to use
                ArrayOfRealItemsType items = responseMessage.RootFolder.Item as
                             ArrayOfRealItemsType;
                if (items.Items == null)
                {
                    // no items in the view.                    
                    return null;
                }
                // Create our response list               
                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:

C#
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.

C#
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:

C#
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:

C#
RestrictionType objRestrictionType = new RestrictionType();

In searching, we have two options:

  1. search on single property like subject or sentdatetime etc.
  2. search on multiple properties like subject and sentdatetime and etc.

For single property searching we need to create the object of OrType as

C#
OrType orType = new OrType();

Else for multiple

C#
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.”

C#
ContainsExpressionType expressionType = null;
List<searchexpressiontype> searchExps = null;

Now for searching for subject

C#
PathToUnindexedFieldType path.FieldURI = UnindexedFieldURIType.itemSubject;
expressionType = new ContainsExpressionType();
expressionType.Item = path;
expressionType.ContainmentMode = ContainmentModeType.Substring; //seach for substrings
expressionType.ContainmentModeSpecified = true;
expressionType.ContainmentComparison =
    ContainmentComparisonType.IgnoreCaseAndNonSpacingCharacters;
expressionType.ContainmentComparisonSpecified = true;
expressionType.Constant = new ConstantValueType();
expressionType.Constant.Value = "Hi"; //search for any string containing 
searchExps.Add(expressionType);

Similarly we can iterate for as many properies as we want:

Now for andType

C#
andType.Items = searchExps.ToArray();
objRestrictionType.Item = andType;

for OrType

C#
orType.Items = searchExps.ToArray();
objRestrictionType.Item = orType;

For this restriction type object we need to set in findrequest as:

C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Brij is a 3-times Microsoft MVP in ASP.NET/IIS Category and a passionate .NET developer. More than 6 years of experience in IT field, currently serving a MNC as a Tech Lead/Architect.

He is a very passionate .NET developer and have expertise over Web technologies like ASP.NET 2.0/3.5/4.0, jQuery, JSON, Javascript, IIS and related technologies. He is also a Exchange Server (EWS) Specialist. He has great experience in design patterns and N-Tier Architecture.

He is also certified as Microsoft Certified Technologies Specialist-ASP.NET and Microsoft Certified Technologies Specialist-WCF in .NET 4.0. He has also received several awards at various forums and his various articles got listed as "Article of the day" at ASP.NET Microsoft Official Website www.asp.net.

He has done MCA from NIT Durgapur and completed his graduation from Lucknow University.

Learning new technologies and sharing knowledge excites him most. Blogging, solving problems at various forums, helping people, keeps him busy entire day.


Visit his Blog: Code Wala

Area of Expertise :
C#, ASP.NET 2.0,3.5,4.0, AJAX, JQuery, JSON, XML, XSLT, ADO.Net, WCF, Active Directory, Exchange Server 2007 (EWS), Java script, Web Services ,Win services, DotnetNuke, WSS 3.0,Sharepoint Designer, SQL Server 2000/2005/2008

Comments and Discussions

 
GeneralRe: My vote of 1 Pin
Brij27-Oct-09 21:04
mentorBrij27-Oct-09 21:04 
QuestionWhat is List<messagetype></messagetype> Pin
Bhavneet8328-Sep-09 7:30
Bhavneet8328-Sep-09 7:30 
AnswerRe: What is List Pin
Brij27-Oct-09 21:22
mentorBrij27-Oct-09 21:22 
GeneralMissing "fieldsOrder[0].Item = pathSortField" Pin
rajni06.sharma26-Aug-09 4:13
rajni06.sharma26-Aug-09 4:13 
GeneralRe: Missing "fieldsOrder[0].Item = pathSortField" Pin
Brij26-Sep-09 19:57
mentorBrij26-Sep-09 19:57 
GeneralDownload Pin
pault711-Feb-09 4:18
pault711-Feb-09 4:18 
GeneralRe: Download Pin
Brij15-Feb-09 3:48
mentorBrij15-Feb-09 3:48 
GeneralRetrieving Email Address of the sender Pin
wallacej26-Nov-08 6:13
wallacej26-Nov-08 6:13 
GeneralRe: Retrieving Email Address of the sender Pin
Brij26-Nov-08 18:17
mentorBrij26-Nov-08 18:17 
GeneralRe: Retrieving Email Address of the sender Pin
wallacej26-Nov-08 22:41
wallacej26-Nov-08 22:41 
GeneralGreat !! Pin
Abhijit Jana16-Nov-08 16:51
professionalAbhijit Jana16-Nov-08 16:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.