Получить встречу с календарем организатора с помощью EWS для Exchange 2010 - PullRequest
9 голосов
/ 30 сентября 2010

У меня есть приложение синхронизации с синхронизацией встреч с Exchange 2010, и у меня есть несколько вопросов.

  1. Пользователь A создает встречу и добавляет пользователя B в качестве посетителя, это означает, что пользователь A является организатором встречи, а в календаре Outlook User Outlook будет создана запись о встрече.
  2. Пользователь календаря UserA и UserB будут иметь свои собственные идентификаторы (UniqueID).
  3. Если, например, мне дается только идентификатор (уникальный идентификатор) календарной встречи пользователя B, это метод для получения календарной встречи пользователя А? Поскольку я думаю, что они должны быть некоторой связью между организатором и назначением участников, я просто не знаю, как.

1 Ответ

18 голосов
/ 25 марта 2011

Для всех, кто придет за мной - вот подробности того, как это работает. Также я опубликую ссылку на свой блог с исходными файлами.

Вкратце - встречи связываются вместе с помощью свойства UID. Это свойство также называется CleanUniqueIdentifier. Хотя этот пример кода может быть скорректирован на основе исправления «ошибки», упомянутого в сообщении блога ниже, этот исходный код выполнен, потому что требования должны работать с => 2007 SP1.

Это предполагает, что у вас есть предварительные знания о том, что такое EWS и как его использовать ( EWS API ). Это также строится из поста в блоге " EWS: UID не всегда одинаков для потерянных экземпляров одного и того же собрания " и поста " Поиск собрания с определенным UID с помощью Exchange Web Services 2007"

Необходимые настройки для работы:

  1. Учетная запись пользователя, которая может быть «Делегатом» или иметь привилегии «Олицетворение» для соответствующих учетных записей.

Проблема: Каждое «назначение» в обмене имеет уникальный идентификатор (Appointment.Id), который является точным идентификатором экземпляра. Имея этот идентификатор, как можно найти все связанные экземпляры (повторяющиеся или запросы посетителей) в календаре?

Приведенный ниже код описывает, как это можно сделать.

[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( "Test2@contoso.com" ) );

    //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 );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...