Thursday, December 4, 2008

Working with Exchange Web Services


Before you even start working with any of the EWS make sure you get your hands on a copy of Inside Microsoft® Exchange Server 2007 Web Services by David Sterling; Benjamin Spain; Michael Mainer; Mark Taylor; Huw Upshall.
Or at least get the sample code for it from here.
This book has explained many things especially around working with the UpdateItem call and Exchange Impersonation and the double hop problem with Kerberos Authentication.

Tuesday, December 2, 2008

My ExchangeServiceBinding.UpdateItem Method Wrapper for Calendar Items

Anyone who's tried to update an item in Exchange using Exchange Web Service (EWS) has felt the pain of the update method. Here is my wrapper as it is today. Will update this as I get more properties I need to update.

/// <summary>
/// Updates the calendar item.
/// </summary>
/// <param name="binding">The binding.</param>
/// <param name="appointment">The appointment.</param>
/// <returns></returns>
public static ItemIdType UpdateCalendarItem(
ExchangeServiceBinding binding,
CalendarItemType appointment)
{
//Category
SetItemFieldType categoryUpdate = new SetItemFieldType();
categoryUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)categoryUpdate.Item).FieldURI = UnindexedFieldURIType.itemCategories;
categoryUpdate.Item1 = new CalendarItemType();
((CalendarItemType)categoryUpdate.Item1).Categories = appointment.Categories;

//Sensitivity
SetItemFieldType sensitivityUpdate = new SetItemFieldType();
sensitivityUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)sensitivityUpdate.Item).FieldURI = UnindexedFieldURIType.itemSensitivity;
sensitivityUpdate.Item1 = new CalendarItemType();
((CalendarItemType)sensitivityUpdate.Item1).Sensitivity = appointment.Sensitivity;
((CalendarItemType)sensitivityUpdate.Item1).SensitivitySpecified = appointment.SensitivitySpecified;

//Subject
SetItemFieldType subjectUpdate = new SetItemFieldType();
subjectUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)subjectUpdate.Item).FieldURI = UnindexedFieldURIType.itemSubject;
subjectUpdate.Item1 = new CalendarItemType();
((CalendarItemType)subjectUpdate.Item1).Subject = appointment.Subject;

//Location
SetItemFieldType locationUpdate = new SetItemFieldType();
locationUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)locationUpdate.Item).FieldURI = UnindexedFieldURIType.calendarLocation;
locationUpdate.Item1 = new CalendarItemType();
((CalendarItemType)locationUpdate.Item1).Location = appointment.Location;

//Start
SetItemFieldType startUpdate = new SetItemFieldType();
startUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)startUpdate.Item).FieldURI = UnindexedFieldURIType.calendarStart;
startUpdate.Item1 = new CalendarItemType();
((CalendarItemType)startUpdate.Item1).Start = appointment.Start;
((CalendarItemType)startUpdate.Item1).StartSpecified = appointment.StartSpecified;

//End
SetItemFieldType endUpdate = new SetItemFieldType();
endUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)endUpdate.Item).FieldURI = UnindexedFieldURIType.calendarEnd;
endUpdate.Item1 = new CalendarItemType();
((CalendarItemType)endUpdate.Item1).End = appointment.End;
((CalendarItemType)endUpdate.Item1).EndSpecified = appointment.EndSpecified;

//IsAllDayEvent
SetItemFieldType isAllDayEventUpdate = new SetItemFieldType();
isAllDayEventUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)isAllDayEventUpdate.Item).FieldURI = UnindexedFieldURIType.calendarIsAllDayEvent;
isAllDayEventUpdate.Item1 = new CalendarItemType();
((CalendarItemType)isAllDayEventUpdate.Item1).IsAllDayEvent = appointment.IsAllDayEvent;
((CalendarItemType)isAllDayEventUpdate.Item1).IsAllDayEventSpecified = appointment.IsAllDayEventSpecified;

//Body
SetItemFieldType bodyUpdate = new SetItemFieldType();
bodyUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)bodyUpdate.Item).FieldURI = UnindexedFieldURIType.itemBody;
bodyUpdate.Item1 = new CalendarItemType();
((CalendarItemType)bodyUpdate.Item1).Body = appointment.Body;

ItemChangeType changes = new ItemChangeType();
changes.Item = appointment.ItemId;

if (appointment.Recurrence != null)
{
//Recurrence
SetItemFieldType recurrenceUpdate = new SetItemFieldType();
recurrenceUpdate.Item = new PathToUnindexedFieldType();
((PathToUnindexedFieldType)recurrenceUpdate.Item).FieldURI = UnindexedFieldURIType.calendarRecurrence;
recurrenceUpdate.Item1 = new CalendarItemType();
((CalendarItemType)recurrenceUpdate.Item1).Recurrence = appointment.Recurrence;

changes.Updates = new ItemChangeDescriptionType[] {
categoryUpdate,
sensitivityUpdate,
subjectUpdate,
locationUpdate,
startUpdate,
endUpdate,
isAllDayEventUpdate,
bodyUpdate,
recurrenceUpdate };
}
else
{
changes.Updates = new ItemChangeDescriptionType[] {
categoryUpdate,
sensitivityUpdate,
subjectUpdate,
locationUpdate,
startUpdate,
endUpdate,
isAllDayEventUpdate,
bodyUpdate };
}

UpdateItemType request = new UpdateItemType();
request.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;
request.MessageDisposition = MessageDispositionType.SaveOnly;
request.SendMeetingInvitationsOrCancellations = CalendarItemUpdateOperationType.SendToNone;
request.SendMeetingInvitationsOrCancellationsSpecified = true;
request.ConflictResolution = ConflictResolutionType.AutoResolve;

request.ItemChanges = new ItemChangeType[] { changes };

UpdateItemResponseType response = binding.UpdateItem(request);

// Verify that the UpdateItem request was successful
if (response.ResponseMessages.Items[0].ResponseClass !=
ResponseClassType.Success)
{
// Indicate that we have a problem
throw new SyncFailedException(String.Format(
"Unable to update occurence\r\n{0}\r\n{1}\r\n{2}",
response.ResponseMessages.Items[0].ResponseCode,
response.ResponseMessages.Items[0].MessageText,
Serializer.SerializeObject<UpdateItemType>(request)));
}

// Success, get the new id of the recurring master
ItemInfoResponseMessageType itemInfoResponseMessage =
(ItemInfoResponseMessageType)response.ResponseMessages.Items[0];

return itemInfoResponseMessage.Items.Items[0].ItemId;
}

Monday, December 1, 2008

CAML Queries in SharePoint

There we go. ot even one day into it and I have my first blunder to talk about. I've been using CAML Queries in SharePoint or a while now, they are fast and really easy t use ........ well if you using something like CAML Query Builder.
No idea how many times I've used this now but today it had me stumped. I used it to build me a querry, which I tested and everything worked great ..... until I put it in my code. The it suddenly just returned everything in the list I was running the query on. This took me almost 30 minutes to and another set of eyes to solve.
Huge FYI everyone, when ya copy the query string out of CAML Query Builder DO NOT copy the <query> <\query> tags and the start and end.

Ok you can laugh at me now :D

What I come across at work!

Hi all,
Ever since I've started working at Intergen, I've been learning a tonne. But on my current project I've been coming across some issues that have been so frustrating I'm starting to question my career as a developer.
Don't get me wrong, I love a challenge but I wouldn't wish this sorta frustration on anyone so in an effort to make this a better world I will share with you everything I find out. From now on anyways :)