Tuesday, October 13, 2009

Exchange Web Services Managed API Release Candidate – Part 2

Developing the every day Line Of Business Applications (LOBA) often includes handling various types of information. When dealing with custom CRM system you often need to collect and bind typed data sources together. One of these sources is often emails but of its good features i.e. handling unstructured information is also its worst. Fortunately the Exchange Server 2007 SP1 and EWS api provides us with tools and handles to enable us to structure and categorize all types of information in a Exchange Mailbox Store. When making connections between two systems some patterns always emerge. The first is you need an unique item key from the source system to store in the destination system to make a one way connection. This strategy has a flaw because when the source item is deleted you need to remove the reference key in the destination. In this case people tend to delete items though outlook and not your LOBA and outlook does not contact you LOBA to tell you have to delete the reference. So the before mentioned strategy flaw was the tight coupling of information between the source and destination.

So let me suggest another solution. Lets say you what to connect you LOBA with a item from a Exchange Mailbox. Instead of storing the Exchange Item ID in you LOBA try instead tag the Exchange Item with the item id from you LOBA you want to connect with. Then from the LOBA, search the Mailbox for items tagged with the LOBA item id. In this way when some elements has been deleted you do not end up with lost keys because the search will not return items that has been deleted. For making this work we need to handle to things: Item Extended Properties and the ability to search for these items.

Working with extended properties

To illustrate how to work with extended properties I will make use of an email object and store it in the default Innbox

   1: //Setup the request. es is an instance of ExchangeService

   2: EmailMessage em = new EmailMessage(es);

   3: em.Subject = "Hello World!";

   4: em.Body = "Your base belongs to us!";

   5: //Creating the Extended property CustomerID as a type of string

   6: ExtendedPropertyDefinition epd = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, "CustomerID", MapiPropertyType.String);

   7: //Give the property a value and assigning it to the email

   8: em.SetExtendedProperty(epd, "1234");

   9: // Store the message in the inbox

  10: em.Save(WellKnownFolderName.Inbox);

Searching form Extended Properties

   1: //Defining a view/windows into the search result.

   2: ItemView view = new ItemView(50);

   3: //Telling that i am only interested in the id of the item.

   4: view.PropertySet = new PropertySet(BasePropertySet.IdOnly);

   5: //Creating a extended property definition to search for.

   6: ExtendedPropertyDefinition epdCustomerID = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, "CustomerID", MapiPropertyType.String);


   8: //Variable for storing the searchresult

   9: FindItemsResults<Item> foundItems;


  11: do

  12: {   

  13:     //Search the inbox for at item with a extended property value stet to 1234

  14:     foundItems = es.FindItems(WellKnownFolderName.Inbox, new SearchFilter.IsEqualTo(epdCustomerID, "1234"), view);

  15:     foreach (Item current in foundItems)

  16:     {

  17:         //Getting the email message from the Exchange Service via the item id.

  18:         EmailMessage email = EmailMessage.Bind(es, current.Id) ;

  19:         Console.WriteLine("Message found. Subject: {0} - Body: {1}", email.Subject, email.Body);

  20:     }

  21:     //Offset the index of the view/windows with 50. This gives the ablity to page through larger resulset.

  22:     view.Offset += 50;

  23:     //while there more result available...

  24: } while (foundItems.MoreAvailable);

Other cool things

The item id can still be very valuable for your LOBA. If you store the id in you LOBA you can always find the item again even if a user decides to move the message to another folder. By using the EmailMessage.Bind method with the item id you will always get the message returned. Same thing goes for folders they also have a id. So even if the users decide to reorganize the folders with the folder id you can still find the folder again.

No comments: