Exchange WebServices (EWS): UpdateItemTypeRequest

Wie man Einträge in Exchange über die WebServices Schnittstelle anlegt ist in einigen Artikeln schon erwähnt. Link

Wer schon einmal versucht hat diese Einträge per WebService zu ändern kann unter Umständen verzweifeln. Es sieht zunächst so aus als könne man pro Update-Request nur eine Eigenschaft ändern.

Im Prinzip funktioniert ein Update so:

  • ExchangeServiceBinding erstellen
  • Eintrag per GetItem oder FindItem ermitteln
  • Einen UpdateItemRequest mit den Änderungen zusammenbauen und wegschicken

Als Basis für einen solchen Request (in unserem Fall Appointments im Kalender) wird ein CalendarItemType zusammengebaut welches nur die Änderungen enthält:

 //Exchange ItemID aus FindItem oder GetItem
ItemIdType itemId = "xxxx";
//ChangeKey aus FindItem oder GetItem
itemId.Id = "yyyy";
itemId.ChangeKey = this.txtChangeKey.Text.ToString();
 
// Objekt für die Änderungen anlegen
CalendarItemType setCalendar1 = new CalendarItemType();
setCalendar1.ReminderMinutesBeforeStart = "0";
 
 
// Feldliste für den Update-Request vorbereiten
 
SetItemFieldType setItemField = new SetItemFieldType();
setItemField.Item = new PathToUnindexedFieldType();
(setItemField.Item as PathToUnindexedFieldType).FieldURI = 
UnindexedFieldURIType.itemReminderMinutesBeforeStart;
setItemField.Item1 = setCalendar1;
 
// Update-Request erstellen.
UpdateItemType updateItemRequest = new UpdateItemType();
updateItemRequest.ItemChanges = new ItemChangeType[1];
ItemChangeType itemChange = new ItemChangeType();
itemChange.Item = itemId;
itemChange.Updates = new ItemChangeDescriptionType[1];
itemChange.Updates[0] = setItemField;
updateItemRequest.ItemChanges[0] = itemChange;
 
//und wegschicken
updateItemRequest.SendMeetingInvitationsOrCancellations = false;
//nur für Kaendereinträge notwendig
updateItemRequest.SendMeetingInvitationsOrCancellationsSpecified = true;
CalendarItemUpdateOperationType.SendToNone;
 
updateItemRequest.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;
UpdateItemResponseType updateItemResponse = esb.UpdateItem(updateItemRequest);
 
// Was kommt zurück ?
ItemInfoResponseMessageType responseMessage = updateItemResponse.ResponseMessages.Items[0] 
as ItemInfoResponseMessageType;
 

Wenn man jetzt mehrere Felder im setCalendar1 Objekt setzt und die Feldliste entsprechend aufbaut wird man jedoch keinen Erfolg haben. Foldender Fehler würde vom UpdateItemRequest Call zurückgeliefert:

Property count mismatch

Abhilfe für dieses Problem ist jedoch möglich. Jeder Change (also jede geänderte Eigenschaft) braucht ihr eigenes CalendarItemType Objekt.

Für 2 Eigenschaften sieht der Code dann wie folgt aus:

 // Objekt für die Änderungen anlegen
CalendarItemType setCalendar1 = new CalendarItemType();
setCalendar1.ReminderMinutesBeforeStart = "0";
 
// Feldliste für den Update-Request vorbereiten
 SetItemFieldType setItemField = new SetItemFieldType();
setItemField.Item = new PathToUnindexedFieldType();
(setItemField.Item as PathToUnindexedFieldType).FieldURI = UnindexedFieldURIType.itemReminderMinutesBeforeStart;
setItemField.Item1 = setCalendar1;
            
// 2. CalendarItemType Objekt für die 2. Eigenschaft 

CalendarItemType setCalendar2 = new CalendarItemType();
setCalendar1.ReminderIsSet = true;
setCalendar1.ReminderIsSetSpecified = true;

//2. Feld für die Feldliste
SetItemFieldType setItemField2 = new SetItemFieldType();
setItemField2.Item = new PathToUnindexedFieldType();
(setItemField2.Item as PathToUnindexedFieldType).FieldURI = UnindexedFieldURIType.itemReminderIsSet;
setItemField2.Item1 = setCalendar2;

// Update-Request erstellen.
UpdateItemType updateItemRequest = new UpdateItemType();
updateItemRequest.ItemChanges = new ItemChangeType[1];
ItemChangeType itemChange = new ItemChangeType();
itemChange.Item = itemId;

//Jetzt sind es 2 Felder / also auch 2 Änderungen
itemChange.Updates = new ItemChangeDescriptionType[2];
itemChange.Updates[0] = setItemField;
itemChange.Updates[1] = setItemField2;
updateItemRequest.ItemChanges[0] = itemChange;

//und wegschicken
updateItemRequest.SendMeetingInvitationsOrCancellations = 
//nur für Kaendereinträge notwendig
updateItemRequest.SendMeetingInvitationsOrCancellationsSpecified = true;
CalendarItemUpdateOperationType.SendToNone;
 
updateItemRequest.ConflictResolution = ConflictResolutionType.AlwaysOverwrite;
UpdateItemResponseType updateItemResponse = esb.UpdateItem(updateItemRequest);
 
// Was kommt zurück ?
ItemInfoResponseMessageType responseMessage = updateItemResponse.ResponseMessages.Items[0] 
as ItemInfoResponseMessageType;
 

Trickreich aber schön :-)

Happy Calendaring

Sven