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:
- 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);
}
}
Nadie tiene alguna idea? – ahlun