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 = @"http://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);
    }
  }
}
Comments (12)

  1. anoop says:

    an article for Pull Subscriptions using Exchange 2007 web service

  2. anoop says:

    I would love to have an active bloggin for exchange 2007 stufss since no where in internet is having enough articles

  3. Daniel says:

    Dear, would it be possible to add a meeting to MS Exchange through the new Web services or throught ADSI or anyway you think it can happen. Thanks.

  4. Rajiv says:

    I want to create an item to be sent on desired future date. How and where in EWS I can do that. Do you have any snippet code which does this?

  5. Bob says:

    Hi SGriffin:

    I want to know how to add custom Internet Message Header in Messages , and then I can get it by your program up…

    Can you give me some tips?

    thank you very much!!

  6. Internet message headers are there on a message that came in from the internet. So the answer would depend greatly on how you plan on creating and sending your messages.

  7. Aaron says:

    Hi SGriffin

    I was looking at your previous reply and the sample. So, if I want to duplicate a message after I delete the original from Exchange, would I be able to do so using EWS or any means of Exchange 2007 SDK, keeping the same MAPI properties and Internet Headers?

    Thanks so much,

    Aaron

  8. Neil says:

    Hi Grifin,

    My question is also similar to bob…

    how can we add custom Internet Message Header in a Mail Message created using createItem request in EWS.

    suppose i want to add a header like

    msg-originator=abc.def.com

    Please give me some inputs..

    TIA

    ~Neil

  9. Tomas says:

    HI Grifin,

    How can I specify which X-Header to get back from the response ? I already know the message header I’m interested in ? Is it possible to specify it via GetItem request ?

    thx

    Thomas

  10. I’ve put together a list of articles which cover common questions on Exchange Web Services (EWS). These

  11. I’ve put together a list of articles which cover common questions on Exchange Web Services (EWS). These