2010-09-30 14 views
9

Tengo una aplicación de sincronización con citas de sincronización con Exchange 2010, y tengo algunas preguntas.Obtenga la cita del calendario del organizador utilizando EWS para Exchange 2010

  1. UserA crea una cita y agrega el usuario B como asistente, esto significa que UserA es el organizador de la cita y que el calendario de la perspectiva de UserB tendrá una entrada de cita creada.
  2. La cita de usuario de UserA y UserB tendrá sus propios ID (UniqueID).
  3. Si, por ejemplo, solo se me proporciona el ID (UniqueID) de la cita del calendario del Usuario B, ¿es ese un método para recuperar la cita del calendario de la UserA? Porque creo que deberían ser un vínculo entre el organizador y la cita de los asistentes, simplemente no sé cómo.
+0

Nadie tiene alguna idea? – ahlun

Respuesta

18

Para cualquier persona que me siga, aquí están los detalles sobre cómo funciona esto. También publicaré una referencia a mi blog con archivos fuente.

En resumen: las citas se vinculan utilizando la propiedad UID. Esta propiedad también se denomina CleanUniqueIdentifier. Si bien este código de ejemplo se puede ajustar en función de una corrección de "error" a la que se hace referencia en la publicación del blog a continuación, este código fuente se hace porque los requisitos son para trabajar con => 2007 SP1.

Esto supone que tiene un conocimiento previo de lo que es el EWS y cómo usarlo (EWS API). Esto también está construyendo fuera de la entrada de blog "EWS: UID not always the same for orphaned instances of the same meeting" y después "Searching a meeting with a specific UID using Exchange Web Services 2007"

Configuración necesaria para que esto funcione:

  1. cuenta de usuario que puede ser un "delegado" o tiene privilegios "suplantación" para los respectivos cuentas

Problema: Cada "cita" a cambio tiene un ID único (Nombramiento.ID) que es el identificador de instancia exacto. Al tener esta identificación, ¿cómo puede uno encontrar todas las instancias relacionadas (solicitudes recurrentes o de asistentes) en un calendario?

El siguiente código describe cómo se puede lograr esto.

[TestFixture] 
public class BookAndFindRelatedAppoitnmentTest 
{ 
    public const string ExchangeWebServiceUrl = "https://contoso.com/ews/Exchange.asmx"; 

    [Test] 
    public void TestThatAppointmentsAreRelated() 
    { 
    ExchangeService service = GetExchangeService(); 

    //Impersonate the user who is creating the Appointment request 
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "Test1"); 
    Appointment apptRequest = CreateAppointmentRequest(service, new Attendee("[email protected]")); 

    //After the appointment is created, we must rebind the data for the appointment in order to set the Unique Id 
    apptRequest = Appointment.Bind(service, apptRequest.Id); 

    //Impersonate the Attendee and locate the appointment on their calendar 
    service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "Test2"); 
    //Sleep for a second to let the meeting request propogate YMMV so you may need to increase the sleep for this test 
    System.Threading.Thread.Sleep(1000); 
    Appointment relatedAppt = FindRelatedAppointment(service, apptRequest); 

    Assert.AreNotEqual(apptRequest.Id, relatedAppt.Id); 
    Assert.AreEqual(apptRequest.ICalUid, relatedAppt.ICalUid); 
    } 

    private static Appointment CreateAppointmentRequest(ExchangeService service, params Attendee[] attendees) 
    { 
    // Create the appointment. 
    Appointment appointment = new Appointment(service) 
    { 
     // Set properties on the appointment. 
     Subject = "Test Appointment", 
     Body = "Testing Exchange Services and Appointment relationships.", 
     Start = DateTime.Now, 
     End = DateTime.Now.AddHours(1), 
     Location = "Your moms house", 
    }; 

    //Add the attendess 
    Array.ForEach(attendees, a => appointment.RequiredAttendees.Add(a)); 

    // Save the appointment and send out invites 
    appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy); 

    return appointment; 
    } 

    /// <summary> 
    /// Finds the related Appointment. 
    /// </summary> 
    /// <param name="service">The service.</param> 
    /// <param name="apptRequest">The appt request.</param> 
    /// <returns></returns> 
    private static Appointment FindRelatedAppointment(ExchangeService service, Appointment apptRequest) 
    { 
    var filter = new SearchFilter.IsEqualTo 
    { 
     PropertyDefinition = new ExtendedPropertyDefinition 
     (DefaultExtendedPropertySet.Meeting, 0x03, MapiPropertyType.Binary), 
     Value = GetObjectIdStringFromUid(apptRequest.ICalUid) //Hex value converted to byte and base64 encoded 
    }; 

    var view = new ItemView(1) { PropertySet = new PropertySet(BasePropertySet.FirstClassProperties) }; 

    return service.FindItems(WellKnownFolderName.Calendar, filter, view).Items[ 0 ] as Appointment; 
    } 

    /// <summary> 
    /// Gets the exchange service. 
    /// </summary> 
    /// <returns></returns> 
    private static ExchangeService GetExchangeService() 
    { 
    //You can use AutoDiscovery also but in my scenario, I have it turned off  
    return new ExchangeService(ExchangeVersion.Exchange2007_SP1) 
    { 
     Credentials = new System.Net.NetworkCredential("dan.test", "Password1"), 
     Url = new Uri(ExchangeWebServiceUrl) 
    }; 
    } 

    /// <summary> 
    /// Gets the object id string from uid. 
    /// <remarks>The UID is formatted as a hex-string and the GlobalObjectId is displayed as a Base64 string.</remarks> 
    /// </summary> 
    /// <param name="id">The uid.</param> 
    /// <returns></returns> 
    private static string GetObjectIdStringFromUid(string id) 
    { 
    var buffer = new byte[ id.Length/2 ]; 
    for (int i = 0; i < id.Length/2; i++) 
    { 
     var hexValue = byte.Parse(id.Substring(i * 2, 2), System.Globalization.NumberStyles.AllowHexSpecifier); 
     buffer[ i ] = hexValue; 
    } 
    return Convert.ToBase64String(buffer); 
    } 
} 
Cuestiones relacionadas