2
votes

We have a problem deleting Appointments from Exchange using EWS.

We try to delete Appointments from Exchange like this

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
service.Credentials = CurrentUser; // NetworkCredential
service.Url = new Uri(WebserviceAddress);
service.UseDefaultCredentials = false;

var appointment = Appointment.Bind(service, id);
deletedAppointment.Delete(DeleteMode.MoveToDeletedItems, SendCancellationsMode.SendToAllAndSaveCopy);

We get an exception with the message "Object cannot be deleted."

Microsoft.Exchange.WebServices.Data.ServiceResponseException was caught Message=Object cannot be deleted.
Source=Microsoft.Exchange.WebServices StackTrace: at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary() at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute() at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalDeleteItems(IEnumerable1 itemIds, DeleteMode deleteMode, Nullable1 sendCancellationsMode, Nullable1 affectedTaskOccurrences, ServiceErrorHandling errorHandling) at Microsoft.Exchange.WebServices.Data.ExchangeService.DeleteItem(ItemId itemId, DeleteMode deleteMode, Nullable1 sendCancellationsMode, Nullable1 affectedTaskOccurrences) at Microsoft.Exchange.WebServices.Data.Item.InternalDelete(DeleteMode deleteMode, Nullable1 sendCancellationsMode, Nullable1 affectedTaskOccurrences) at Microsoft.Exchange.WebServices.Data.Appointment.Delete(DeleteMode deleteMode, SendCancellationsMode sendCancellationsMode) at OurNameSpace.ExchangeCalendar.ViewCalendars.ExchangeMethods.DeleteMeeting(ItemId id) InnerException:

If we instead try to use cancel the meeting

deletedAppointment.CancelMeeting();

we get an exception with the message "User must be an organizer for CancelCalendarItem action." This makes me really confused, because when I inspect the deletedAppointment object my email address is set as the organizer.

We create our meetings like this

Appointment appointment = new Appointment(service);
appointment.Subject = subject;
appointment.Body = body;
appointment.Start = start;
appointment.End = end;
appointment.Location = location;
appointment.RequiredAttendees.Add(location);
appointment.RequiredAttendees.Add(requiredAttendees);
try
{
    appointment.Save(SendInvitationsMode.SendOnlyToAll);
}
catch ...

location contains the name of a conference room mailbox.
if we pause a while (until the Appointment appears in Outlook) and call Delete on the same Appointment instance we used when we created the meeting the appointment is deleted successfully.

The code runs in a custom SharePoint 2010 WebPart. Not that I could think that it would make any difference, but who knows?

Why can't I delete the appointment?
How can I investigate further?
As far as I can see the code is mostly copy'n paste of an MSDN example.

Edit
When I copy a minimal example of the code to a Winform application the meeting is deleted correctly. Could there be any critical difference when running in the Sharepoint context?

Edit 2
CurrentUser is a user supplied username and password. The Exchange server is not on the same domain as SharePoint server.

Edit 3
If I open the appointment in outlook (with the same login as in the CurrentUser variable) I can cancel the appointment.

2
the sharepoint context changes permissions etc. - the identity the Exchange sees is different from the one it sees on your Winforms application... either impersoante the needed identity and/or use an administrative user explicitly for the connection to Exchange...Yahia
@Yahia, I guess I was not not clear enough that I supply user specific Exchange credentials in the CurrentUser variable and that the Exchange server is not on the same domain as the SharePoint server.Albin Sunnanbo
that alone won't do it - my explanation seems to be unclear... check this 15seconds.com/issue/040511.htm and then impersonate the respective user before connecting to Exchange, then connect to Exchange the way you are already doing...Yahia

2 Answers

6
votes

At last we found out that the issue was outside the simplified example above.
The issue was that we used a "view only" account to fetch all the appointments in the calendar. We then tried to use that appointment id when we tried to delete the appointment using the CurrentUser credentials, but that ID was not valid in the context of the new user.
When we changed to retrieve the calendar items with CurrentUser instead of our view only account everything started to work.

Thanks anyway for trying to help.

1
votes

The user performing the delete operation must have enough permissions to delete the Meetings from a specific resource/user's calender.

In case of SharePoint, the web part code will be run under the current logged on user (as visible from your code) however, current logged on user may not have enough rights to perform the operation on every Exchange object's calender. I would recommend setting up a dedicated Active Directory user who will perform the calls from the code and at the same time have full access to manipulate the calendar items of every Exchange Server's object (user or resource).

Here are some useful PowerShell scriptlets to set the permissions for the user and perform the deletion operation again.

Set-MailboxFolderPermission -Identity [email protected]:\Calendar -User Default -AccessRights Reviewer

Set-MailboxFolderPermission -Identity [email protected]:\Calendar -User [email protected]  -AccessRights Owner

Good luck