更新约会会使其更改为EWS 1.1中的会议

tig*_*tig 11 exchange-server exchangewebservices

这是我正在尝试做的事情:

  • 在两个日期之间获取用户日历上的所有项目
  • 更新LocationSubject某些项目

我得到的项目:

FindItemsResults<Appointment> findResults = calendar.FindAppointments(new CalendarView(startDate, endDate));

此查询工作正常.但每当我调用Update来保存项目时,我都会遇到异常:

Microsoft.Exchange.WebServices.Data.ServiceResponseException: One or more recipients are invalid.

即使我收到异常,该项目也会保存并更改为IsMeeting设置为true!现在更新的项目是与组织者等的会议......这实际上是对我来说数据损坏.

这是代码.它并不复杂.我只需更改测试它LocationSubject两者引起的问题.

Appointment a = Appointment.Bind(_service, new ItemId(id));
a.Location = newLocation
a.Update(ConflictResolutionMode.AlwaysOverwrite);
Run Code Online (Sandbox Code Playgroud)

我错过了一些概念吗?这似乎是一个非常令人震惊的问题.

FWIW,这是针对Office 365服务器的EWS 1.1.

tig*_*tig 16

我在这个问题的帮助下弄明白了:

交换预约类型

关键是Update需要使用SendInvitationsOrCancellationsMode.SendToNone第二个参数中设置的标志调用方法.

像这样:

a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
Run Code Online (Sandbox Code Playgroud)


don*_*van 5

因此,当您从不希望将约会更新发送给其他与会者时,tig的答案就会起作用。但是,要正确回答此问题,您实际上需要加载与会者状态。

默认情况下,它尝试将约会更新发送给与会者,但是约会对象没有加载与会者状态,因此正在爆炸。进行绑定时,您应该加载与会者属性。您可能还应该加载组织器以覆盖另一个边缘情况:

  • AppointmentSchema.Required与会者
  • AppointmentSchema.Optional与会者
  • AppointmentSchema.Resources
  • 约会架构组织者

如果您要进行更新以将更新发送给参与者,则将填充参与者。

但是,还有另一种情况需要您担心。如果您的约会中未添加任何与会者(只是组织者),则EWS可能仍会抱怨并抛出此错误。它实际上可以在某些州进行约会,但在其他州则失败。

因此,最完整的解决方案是以下各项的组合:

  1. 加载与会者状态。
  2. 检查与会者的状态以查看是否有组织者以外的其他与会者(取决于约会的创建方式,组织者可能会或可能不会出现在RequiredAttendees集合中)。如果没有,则必须使用SendInvitationsOrCancellationsMode.SendToNone。

因此完整的样本看起来像:

Appointment a = Appointment.Bind(_service, new ItemId(id), new PropertySet(AppointmentSchema.RequiredAttendees, AppointmentSchema.OptionalAttendees, AppointmentSchema.Resources, AppointmentSchema.Organizer));
a.Location = newLocation

// Check if the appointment has attendees other than the organizer. The organizer may
// or may not appear in the required attendees list.
if (HasNoOtherAttendee(a.Organizer.Address, a.RequiredAttendees) &&
    (a.OptionalAttendees.Count == 0) && (a.Resources.Count == 0))
{
    a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
}
else
{
    // We have other attendees in the appointment, so we can use SendToAllAndSaveCopy so
    // they will see the update.
    a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy);
}


bool HasNoOtherAttendee(string email, AttendeeCollection attendees)
{
    bool emptyOrOnlyMe = true;
    foreach (var a in attendees)
    {
        if (!string.Equals(email, a.Address, StringComparison.OrdinalIgnoreCase))
        {
            emptyOrOnlyMe = false;
            break;
        }
    }
    return emptyOrOnlyMe;
}
Run Code Online (Sandbox Code Playgroud)