OfficeDev / ews-managed-api

Other
584 stars 320 forks source link

Attempting to add appointment attendee results in error "Cannot use personal contacts as recipients or attendees" #69

Open RicksonByArmbar opened 8 years ago

RicksonByArmbar commented 8 years ago

When calling the Update method on an appointment with a new attendee results in the error:

"Cannot use personal contacts as recipients or attendees"

This error message does not appear to be documented anywhere. The attendee is a valid domain user that is present in the global address list. This error appears to only occur for some mailboxes, and I suspect this is when the contact's Item Id is null.

Sample source code snippet:

  private void CreateAppointment(Appointment appointment)
    {

        Attendee attendee = null;
        Attendee manager = null;

        if (attendee != null)
        {
            //manager has not been added: this is first pass through
            if (manager == null)
            {
                //get manager email
                string email = "validUser@domain.com";
                var names = service.ResolveName(email);
                manager = new Attendee(names[0].Mailbox);
                appointment.RequiredAttendees.Add(manager);
            }

        }

        appointment.Update(ConflictResolutionMode.AutoResolve, SendInvitationsOrCancellationsMode.SendOnlyToChanged);

    }

Stack trace is below:

at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary() at Microsoft.Exchange.WebServices.Data.ServiceResponse.ThrowIfNecessary() at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute() at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalUpdateItems(IEnumerable1 items, FolderId savedItemsDestinationFolderId, ConflictResolutionMode conflictResolution, Nullable1 messageDisposition, Nullable1 sendInvitationsOrCancellationsMode, ServiceErrorHandling errorHandling, Boolean suppressReadReceipt) at Microsoft.Exchange.WebServices.Data.ExchangeService.UpdateItem(Item item, FolderId savedItemsDestinationFolderId, ConflictResolutionMode conflictResolution, Nullable1 messageDisposition, Nullable1 sendInvitationsOrCancellationsMode, Boolean suppressReadReceipts) at Microsoft.Exchange.WebServices.Data.Item.InternalUpdate(FolderId parentFolderId, ConflictResolutionMode conflictResolutionMode, Nullable1 messageDisposition, Nullable1 sendInvitationsOrCancellationsMode, Boolean suppressReadReceipts) at Microsoft.Exchange.WebServices.Data.Item.InternalUpdate(FolderId parentFolderId, ConflictResolutionMode conflictResolutionMode, Nullable1 messageDisposition, Nullable1 sendInvitationsOrCancellationsMode) at Microsoft.Exchange.WebServices.Data.Appointment.Update(ConflictResolutionMode conflictResolutionMode, SendInvitationsOrCancellationsMode sendInvitationsOrCancellationsMode) at Infrastructure.Services.ExchangeClient.CreateAppointment(Appointment appointment) at Infrastructure.Services.ExchangeClient.OnEvent(Object sender, NotificationEventArgs args) at Microsoft.Exchange.WebServices.Data.StreamingSubscriptionConnection.IssueNotificationEvents(GetStreamingEventsResponse gseResponse) at Microsoft.Exchange.WebServices.Data.StreamingSubscriptionConnection.HandleServiceResponseObject(Object response) at Microsoft.Exchange.WebServices.Data.HangingServiceRequestBase.ParseResponses(Object state) at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

jkaleta commented 8 years ago

I also encountered this problem. In my case the scenario was that I was updating an existing contact, with a modified list of attendees. In my tests it occurred with Exchange 2010, but not with 2013 (on Office 365).

The offending attendee looked like this:

<t:SetItemField>
<t:FieldURI FieldURI="calendar:RequiredAttendees" />
<t:CalendarItem>
  <t:RequiredAttendees>
    <t:Attendee>
      <t:Mailbox>
        <t:Name>Test (test@example.co.uk)</t:Name>
        <t:EmailAddress>test@example.co.uk</t:EmailAddress>
        <t:RoutingType>SMTP</t:RoutingType>
        <t:MailboxType>Contact</t:MailboxType>
        <t:ItemId Id="AAMkAGM2MmZiMTcy(...)AA=" ChangeKey="EQAAAA==" />
      </t:Mailbox>
    </t:Attendee>
  </t:RequiredAttendees>
</t:CalendarItem>
</t:SetItemField>

After playing with various versions of the above XML, I found out that the only combination that will pass is one without the <t:ItemId/> tag.

My solution - which may be risky - (hard to tell due to lack of documentation) - was to nullify the Id property on all attendees before updating an event in Exchange. Verified that even without the Id, Exchange properly matches the attendee to an existing contact.

Any advise would be greatly appreciated!

davster commented 8 years ago

ItemId element is used ONLY for private DLs and contacts. It would typically be used in lieu of the other properties, not in conjunction with them. So you are correct – feel free to null out those ItemIds. We have to do matching for one-offs and directory contacts anyways since those have no ItemId equivalent. From: Jakub Kaleta [mailto:notifications@github.com] Sent: Friday, February 19, 2016 2:32 AM To: OfficeDev/ews-managed-api ews-managed-api@noreply.github.com Subject: Re: [ews-managed-api] Attempting to add appointment attendee results in error "Cannot use personal contacts as recipients or attendees" (#69)

I also encountered this problem. In my case the scenario was that I was updating an existing contact, with a modified list of attendees. In my tests it occurred with Exchange 2010, but not with 2013 (on Office 365).

The offending attendee looked like this:

``` Test (test@example.co.uk)> test@example.co.uk> SMTP Contact ``` /t:RequiredAttendees /t:CalendarItem /t:SetItemField After playing with various versions of the above XML, I found out that the only combination that will pass is one without the tag. My solution - which may be risky - (hard to tell due to lack of documentation) - was to nullify the Id property on all attendees before updating an event in Exchange. Verified that even without the Id, Exchange properly matches the attendee to an existing contact. Any advise would be greatly appreciated! — Reply to this email directly or view it on GitHubhttps://github.com/OfficeDev/ews-managed-api/issues/69#issuecomment-186161165.