Exchange Web Services and Internet Message Headers

We had a customer asking how to use the InternetMessageHeaders property in EWS. They found that if they asked for the prop, they only got the names of the headers, but not the values. This is one of those areas (like attachments) where EWS is only going to fetch the minimal amount of data, avoiding potentially expensive operations until you explicitly ask for them. In this case, once you have the names of the headers, you can make another call back to fetch their values. Of course, if you already knew the name of a header you wanted, then you could skip the middle step and ask for it directly.

I've updated my earlier sample to illustrate the technique.

 using System;
using EWS;
using System.Net;

namespace GetProps
{
  class Program
  {
    static void Main(string[] args)
    {
      ExchangeServiceBinding exchangeServer = new ExchangeServiceBinding();
      ICredentials creds = new NetworkCredential("SomeUser", "SomePassword", "SomeDomain");

      exchangeServer.Credentials = creds;
      exchangeServer.Url = @"https://MyServer/EWS/Exchange.asmx";

      DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
      folderIDArray[0] = new DistinguishedFolderIdType();
      folderIDArray[0].Id = DistinguishedFolderIdNameType.inbox;

      PathToUnindexedFieldType ptuftDisplayName = new PathToUnindexedFieldType();
      ptuftDisplayName.FieldURI = UnindexedFieldURIType.folderDisplayName;

      PathToExtendedFieldType pteftComment = new PathToExtendedFieldType();
      pteftComment.PropertyTag = "0x3004"; // PR_COMMENT
      pteftComment.PropertyType = MapiPropertyTypeType.String;

      GetFolderType myfoldertype = new GetFolderType();
      myfoldertype.FolderIds = folderIDArray;
      myfoldertype.FolderShape = new FolderResponseShapeType();
      myfoldertype.FolderShape.BaseShape = DefaultShapeNamesType.IdOnly;
      myfoldertype.FolderShape.AdditionalProperties = new BasePathToElementType[2];
      myfoldertype.FolderShape.AdditionalProperties[0] = ptuftDisplayName;
      myfoldertype.FolderShape.AdditionalProperties[1] = pteftComment;

      Console.WriteLine("Getting inbox");
      GetFolderResponseType myFolder = exchangeServer.GetFolder(myfoldertype);

      FolderInfoResponseMessageType firmtInbox = 
      (FolderInfoResponseMessageType) myFolder.ResponseMessages.Items[0];

      Console.WriteLine("got folder: {0}",firmtInbox.Folders[0].DisplayName);

      if (null != firmtInbox.Folders[0].ExtendedProperty)
      {
        Console.WriteLine("Comment: {0}",firmtInbox.Folders[0].ExtendedProperty[0].Item.ToString());
      }
      else
      {
        Console.WriteLine("Comment: not found");
      }

      PathToUnindexedFieldType ptuftSubject = new PathToUnindexedFieldType();
      ptuftSubject.FieldURI = UnindexedFieldURIType.itemSubject;

      PathToExtendedFieldType pteftFlagStatus = new PathToExtendedFieldType();
      pteftFlagStatus.PropertyTag = "0x1090"; // PR_FLAG_STATUS
      pteftFlagStatus.PropertyType = MapiPropertyTypeType.Integer;

      FindItemType findItemRequest = new FindItemType();
      findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
      findItemRequest.ItemShape = new ItemResponseShapeType();
      findItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
      findItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[2];
      findItemRequest.ItemShape.AdditionalProperties[0] = ptuftSubject;
      findItemRequest.ItemShape.AdditionalProperties[1] = pteftFlagStatus;
      findItemRequest.ParentFolderIds = new FolderIdType[] { firmtInbox.Folders[0].FolderId };

      FindItemResponseType firt = exchangeServer.FindItem(findItemRequest);

      foreach (FindItemResponseMessageType firmtMessage in firt.ResponseMessages.Items)
      {
        if (null != firmtMessage.RootFolder && firmtMessage.RootFolder.TotalItemsInView > 0)
        {
          foreach (ItemType it in ((ArrayOfRealItemsType)firmtMessage.RootFolder.Item).Items)
          {
            Console.WriteLine("got item: {0}",it.Subject);
            if (null != it.ExtendedProperty)
            {
              Console.WriteLine("Prop PR_FLAG_STATUS: {0}",it.ExtendedProperty[0].Item.ToString());
            }
            else
            {
              Console.WriteLine("Prop PR_FLAG_STATUS: not found");
            }

            PathToUnindexedFieldType ptuftHeaders = new PathToUnindexedFieldType();
            ptuftHeaders.FieldURI = UnindexedFieldURIType.itemInternetMessageHeaders;

            PathToExtendedFieldType ptuftHeadersProp = new PathToExtendedFieldType();
            ptuftHeadersProp.PropertyTag = "0x007D"; // PR_TRANSPORT_MESSAGE_HEADERS
            ptuftHeadersProp.PropertyType = MapiPropertyTypeType.String;

            GetItemType getItemRequest = new GetItemType();
            getItemRequest.ItemIds = new ItemIdType[] { it.ItemId };
            getItemRequest.ItemShape = new ItemResponseShapeType();
            getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
            getItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[2];
            getItemRequest.ItemShape.AdditionalProperties[0] = ptuftHeaders;
            getItemRequest.ItemShape.AdditionalProperties[1] = ptuftHeadersProp;

            GetItemResponseType girt = exchangeServer.GetItem(getItemRequest);
            foreach (ItemInfoResponseMessageType grmtMessage in girt.ResponseMessages.Items)
            {
              ItemType item = grmtMessage.Items.Items[0];
              if (null != item.ExtendedProperty)
              {
                Console.WriteLine("Prop PR_TRANSPORT_MESSAGE_HEADERS:\n {0}", item.ExtendedProperty[0].Item.ToString());
              }
              else
              {
                Console.WriteLine("Prop PR_TRANSPORT_MESSAGE_HEADERS: not found");
              }
              Console.WriteLine();

              if (null != item.InternetMessageHeaders)
              {
                PathToIndexedFieldType[] headerProps = new PathToIndexedFieldType[item.InternetMessageHeaders.Length];
                int index = 0;
                foreach (InternetHeaderType iht in item.InternetMessageHeaders)
                {
                  PathToIndexedFieldType headerProp = new PathToIndexedFieldType();
                  headerProp.FieldURI = DictionaryURIType.itemInternetMessageHeader;
                  headerProp.FieldIndex = iht.HeaderName;
                  headerProps[index++] = headerProp;
                }

                GetItemType getItemRequest2 = new GetItemType();
                getItemRequest2.ItemIds = new ItemIdType[] { it.ItemId };
                getItemRequest2.ItemShape = new ItemResponseShapeType();
                getItemRequest2.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
                getItemRequest2.ItemShape.AdditionalProperties = headerProps;

                GetItemResponseType girt2 = exchangeServer.GetItem(getItemRequest2);
                foreach (ItemInfoResponseMessageType grmtMessage2 in girt2.ResponseMessages.Items)
                {
                  ItemType item2 = grmtMessage2.Items.Items[0];
                  if (null != item2.InternetMessageHeaders)
                  {
                    Console.Write("Parsing internet headers");
                    foreach (InternetHeaderType iht2 in item2.InternetMessageHeaders)
                    {
                      if (null != iht2.HeaderName)
                      {
                        Console.Write("Header {0}", iht2.HeaderName.ToString());
                        if (null != iht2.Value)
                        {
                          Console.WriteLine(" = {0}", iht2.Value.ToString());
                        }
                        else Console.WriteLine(" is null");
                      }
                    }
                  }
                }
              }
            }
            Console.WriteLine();
          }
        }
      }

      Console.WriteLine("\nHit any key to continue");
      Console.ReadKey(true);
    }
  }
}