I am about to write a ews-application to connect exchange with another calendar programm. What occured to me, how do I get to know, which appointments get deleted on exchange? Is there a way to tell? I couldn't find it in the API and documentation.
Thanks in advance.
Depending on how a user deletes an appointment (or any item), different things are done:
- Soft-Delete: The item is moved to the recycle bin of the mailbox.
- Hard-Delete: The item is instantly removed.
You have multiple ways to get information about deleted items:
- Query the folder using a FindItems call and select ItemTraversal.Associated in the Traversal property of the ItemView. Note: This requires Exchange 2010.
- Use the SyncFolderItems at one time and store the synchronization cookie somewhere. Later, execute the SyncFolderItems again using the previously stored cookie. Exchange will now give you a detailed list of changes which happened to the folder.
- Query the Recycle bin for appointments. They will most likely have come from the default calendar of the user.
I wrote a service that syncs EWS Calendar Appointments to a Sql Table.
For deletion after Inserting/Updating changes if there is a row in the database and not in EWS I will delete it, as this means it was deleted in Exchange. I use GUIDs to track the appointment in database and exchange. Exchange web services: why is ItemId not constant? [continued]
Performance is decent with just couple dozen appointments, I will try it on much larger dataset.
Dim appointmentGuid As New List(Of String)
For Each appointment In appointments 'appointments is IEnumerable(Of Appointment) from EWS
Dim guid As String = GetGuidForAppointment(appointment)
If String.IsNullOrEmpty(guid) Then
SetGuidForAppointment(appointment)
guid = GetGuidForAppointment(appointment)
End If
appointmentGuid.Add(guid)
'Upsert rows
...
Next
'Delete orphaned rows
Using sqlConnection As New SqlConnection(ConnectionString)
Dim deleteScript As New StringBuilder()
Using sqlCmd As New SqlCommand("SELECT ID FROM Appointments", sqlConnection)
Using sqlDataReader As SqlDataReader = sqlCmd.ExecuteReader()
sqlConnection.Open()
While sqlDataReader.Read()
Dim guid As String = sqlDataReader.GetString(0)
If Not appointmentGuid.Contains(guid) Then
deleteScript.AppendFormat("DELETE FROM Appointments WHERE ID = '{0}'; ", guid)
End If
End While
End Using
End Using
If deleteScript.Length > 0 Then
Using sqlCmd As New SqlCommand(deleteScript.ToString(), sqlConnection)
sqlCmd.ExecuteNonQuery()
End Using
End If
End Using