Migrating to Exchange Web Services, Part 4: Contact Management

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

Topic Last Modified: 2008-09-17

By Bob Bunn, Programming Writer

Applications that work with Microsoft Office Outlook and Microsoft Exchange Server typically extend one or more of the following features:

  • Messaging
  • Calendaring (including meetings and appointments)
  • Search
  • Contact management

In the first three articles in this series, I described how to use Exchange Web Services (EWS) to handle messaging, calendaring, and search. In this article, I will explore the last of these common functions: contact management.

Contact Management Overview

The ability to maintain the accuracy of contact information is an important feature for any communication application. The code examples in this article show how to use WebDAV and Exchange Web Services to update the e-mail address and job title fields for a contact.

Using EWS to update fields in a contact or other object differs from legacy APIs in that EWS requires strong typing, which helps prevent data corruption. EWS can send only those properties that have to be updated, instead of entire objects. This conserves bandwidth and improves performance.

Using WebDAV to Update a Contact

The following code example uses WebDAV to update the JobTitle property of a contact.

PROPPATCH /docs/myfile.doc HTTP/1.1
Host: www.contoso.com
Content-Type: text/xml
Content-Length: XXX
Translate: F

<?xml version="1.0"?>
<d:propertyupdate xmlns:d="DAV:"
xmlns:o="urn:schemas-microsoft-com:office:office">
<d:set>
<d:prop>
<o:JobTitle>Senior Market Analyst</o:JobTitle>
</d:prop>
</d:set>
</d:propertyupdate>

In this example, the WebDAV PROPPATCH operation is used to perform an update. The propertyupdate element is populated with a set element that contains the prop element to set the JobTitle property of the contact.

Using Exchange Web Services to Update a Contact

Exchange Web Services uses strongly typed proxy objects to perform updates. This example uses EWS to update two fields: job title and e-mail address.

// Create an object of type UpdateItemType.
UpdateItemType updateRequest = new UpdateItemType();

// When a conflict occurs, always overwrite
// the existing field's values.
updateRequest.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;

// Set up an array that will contain items to change.
updateRequest.ItemChanges = new ItemChangeType[1];
ItemChangeType changeType = new ItemChangeType();

// Create an object of type ItemIdType. 
ItemIdType contactId = new ItemIdType();

// Use the ID and change key from a previous FindItem call
// to set the Id and ChangeKey properties.
contactId.Id = id;
contactId.ChangeKey = changeKey;

// Set the item ID type.
changeType.Item = contactId;

SetItemFieldType jobTitleUpdate = new SetItemFieldType();

// JobTitle is an unindexed field so use 
// PathToUnindexedFieldType to set the path.
path = new PathToUnindexedFieldType();
path.FieldURI = UnindexedFieldURIType.contactsJobTitle;
jobTitleUpdate.Item = path;

// Set up a temporary contact and apply the change to it.
tempContact = new ContactItemType();
tempContact.JobTitle = contact.JobTitle;

// Insert the temporary contact that has the changed JobTitle
// field into the Item1 property of the jobTitleUpdate object.
jobTitleUpdate.Item1 = tempContact;

// E-mail is an indexed collection, 
// so use PathToIndexedFieldType to set the path.
SetItemFieldType emailUpdate = new SetItemFieldType();
PathToIndexedFieldType indexedPath = new PathToIndexedFieldType();
indexedPath.FieldIndex = "EmailAddress1";
indexedPath.FieldURI = DictionaryURIType.contactsEmailAddress;
emailUpdate.Item = indexedPath;

// Apply the second change (e-mail address) to 
// a new temporary contact.
tempContact = new ContactItemType();
tempContact.EmailAddresses =
new EmailAddressDictionaryEntryType[] { contact.EmailAddresses[0] };

// Insert the temporary contact that has the changed e-mail address
// into the Item1 property of the emailUpdate object. 
emailUpdate.Item1 = tempContact;

// Specify the items to update.
changeType.Updates =
new ItemChangeDescriptionType[] { jobTitleUpdate, emailUpdate };

// Set the change type.
updateRequest.ItemChanges[0] = changeType;

// Send the update item request and receive the response.
UpdateItemResponseType updateResponse =
serviceBinding.UpdateItem(updateRequest);

// Verify success.
if (updateResponse.ResponseMessages.Items[0].ResponseClass !=
ResponseClassType.Success)
{
throw new Exception("update failed");
}

Update operations in EWS are handled by constructing update objects of the class ItemChangeDescriptionType. An array of ItemChangeDescriptionType objects defines multiple field changes.

Let's walk through what we are doing in this code to get a better understanding of how this works. The code example updates two fields in a contact, the job title (contactsJobTitle, an unindexed property) and e-mail address (contactsEmailAddress, an indexed property) fields.

First, we create an object of the UpdateItemType class.

UpdateItemType updateRequest = new UpdateItemType();

This object, named updateRequest for this example, will hold the collection of items that are to be updated. The ItemChanges property will hold an array of changes, each change being contained in an ItemChangeType object.

updateRequest.ItemChanges = new ItemChangeType[1];
ItemChangeType changeType = new ItemChangeType();

To update the property of an item, EWS requires a new item of the same type. So to change the Job Title property, we create a temporary contact named tempContact and set its JobTitle property.

tempContact = new ContactItemType();

tempContact.JobTitle = contact.JobTitle;

The updated contact is then put in the Item1 property of the jobTitleUpdate object. This is an object of the class SetItemFieldType.

jobTitleUpdate.Item1 = tempContact;

Similarly, to update the e-mail address property of the contact, we create a new temporary contact, again called tempContact, set the EmailAddresses property, and add the new contact to the Item1 property of the emailUpdate class.

tempContact = new ContactItemType();
tempContact.EmailAddresses =
new EmailAddressDictionaryEntryType[] { contact.EmailAddresses[0] };

We then set up two SetItemFieldType objects to perform the two updates.

SetItemFieldType jobTitleUpdate = new SetItemFieldType();
...
SetItemFieldType emailUpdate = new SetItemFieldType();

Then we assign the updates to the Updates property of the changeType object.

changeType.Updates =
new ItemChangeDescriptionType[] { jobTitleUpdate, emailUpdate };

The collection of changes now in changeType is then assigned to the ItemChanges property of the updateRequest object.

updateRequest.ItemChanges[0] = changeType;

Finally, we call the UpdateItem Web service method and include updateRequest as an argument.

UpdateItemResponseType updateResponse =
serviceBinding.UpdateItem(updateRequest);

The sample code in part five of this series will include an update application that shows how a large part of this process can be automated by using a helper class.