Thursday, August 28, 2008

Exchange 2007 Web Services (III): Update a calendar item (UpdateItem)

In my previous post, I explained how create a calendar item with an extended property and how find this calendar item by the extended property.

In this post, I will explain how to update this calendar item, modifying the appointment's End datetime.

This is the commented code:


public void UpdateAppointment(CalendarItemType calendarItem)
{
try
{
// Delegate to accept server certificate
ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
};

// Init Web Service Instance
ExchangeServiceBinding ewsService = new ExchangeServiceBinding();

// Set credentials and URL
ewsService.Credentials = new NetworkCredential("user", "qwerty", "DOMAIN");
ewsService.Url = @"https://server.domain.com/ews/exchange.asmx";

// If we need pass through a proxy
ewsService.Proxy = new WebProxy("proxy.domain.com", true);
ewsService.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Exchange properties
ewsService.RequestServerVersionValue = new RequestServerVersion();
ewsService.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

// Initialize the instance to pass to the web service method
UpdateItemType updateItem = new UpdateItemType();
updateItem.ItemChanges = new ItemChangeType[1];
updateItem.ItemChanges[0] = new ItemChangeType();

// Set the Calendar Item's ID (the item wich will be updated)
updateItem.ItemChanges[0].Item = calendarItem.ItemId;
updateItem.ItemChanges[0].Updates = new ItemChangeDescriptionType[1];

// The instance to modify the End property
SetItemFieldType setCalendarEnd = new SetItemFieldType();

// The path to the End property
PathToUnindexedFieldType calendarEndPath = new PathToUnindexedFieldType();
calendarEndPath.FieldURI = UnindexedFieldURIType.calendarEnd;

// The new End property's value
CalendarItemType calendarEndItem = new CalendarItemType();
calendarEndItem.End = new DateTime(2008, 08, 28, 17, 00, 00);
// If no -> ErrorIncorrectUpdatePropertyCount
calendarEndItem.EndSpecified = true;

setCalendarEnd.Item = calendarEndPath;
setCalendarEnd.Item1 = calendarEndItem;

updateItem.ItemChanges[0].Updates[0] = setCalendarEnd;

// This property is required in the UpdateItem method, when we update calendar items
updateItem.SendMeetingInvitationsOrCancellations = CalendarItemUpdateOperationType.SendToNone;
updateItem.SendMeetingInvitationsOrCancellationsSpecified = true;

// Invoke the web service method
UpdateItemResponseType response = ewsService.UpdateItem(updateItem);

// Get the response
UpdateItemResponseMessageType updateItemResponse =
(UpdateItemResponseMessageType)response.ResponseMessages.Items[0];

// Check the result
if (updateItemResponse.ResponseClass != ResponseClassType.Success)
{
// An error occurs
Console.Out.WriteLine("[UPDATE ITEM RESULTS]");
Console.Out.WriteLine(updateItemResponse.ResponseClass);
Console.Out.WriteLine(updateItemResponse.ResponseCode);
Console.Out.WriteLine(updateItemResponse.MessageText);
}
else
{
// No error
Console.Out.WriteLine("[UPDATE ITEM RESULTS]");
Console.Out.WriteLine(updateItemResponse.ResponseClass);
Console.Out.WriteLine(updateItemResponse.ResponseCode);
}
}
catch (Exception ex)
{
// An unexpected error
string message = ex.Message;
Console.Out.WriteLine(string.Format("Unexpected error...{0}", message));
}
}
Pay attention to this line:

calendarEndItem.End = new DateTime(2008, 08, 28, 17, 00, 00);
calendarEndItem.EndSpecified = true;

If we don't set EndSpecified property, we will receive a confusing error code: ErrorIncorrectUpdatePropertyCount.

3 comments:

Anonymous said...

Thank you so much for the wonderful example. This is the best implementation of UpdateItem I am yet to find on the web.

Alexis said...

I like searching new programs on the Inet. Several working days before I ran across one utility. It was interested me. The program solved out my old issues with Exchange very simply and moreover might be appropriate for many like difficult situations - exchange inbox repair tool.

matt.bungard said...

For general info (as it applied to me), if you want to set multiple values make these changes (assume 2 fields, instead of one):

updateItem.ItemChanges[0].Updates = new ItemChangeDescriptionType[2];

and

updateItem.ItemChanges[0].Updates[1] = setCalendarStart;

seems pretty obvious now.
Also this page helped too: http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/b8f91d59-9c1f-4a61-8e5d-3e33ca28fd9e/

there are some useful posts on the actual soap messages that are generated.