Exchange server 更新约会会导致约会更改为EWS 1.1中的会议

Exchange server 更新约会会导致约会更改为EWS 1.1中的会议,exchange-server,exchangewebservices,Exchange Server,Exchangewebservices,以下是我想做的: 获取两个日期之间用户日历上的所有项目 更新某些项目的位置或主题 我获得的项目包括: FindItemsResults findResults=calendar.findAppoints(新的CalendarView(startDate,endDate)) 这个查询工作正常。但每当我调用Update保存项目时,都会出现异常: Microsoft.Exchange.WebServices.Data.ServiceResponseException:一个或多个收件人无效。 即使我

以下是我想做的:

  • 获取两个日期之间用户日历上的所有项目
  • 更新某些项目的
    位置
    主题
我获得的项目包括:

FindItemsResults findResults=calendar.findAppoints(新的CalendarView(startDate,endDate))

这个查询工作正常。但每当我调用Update保存项目时,都会出现异常:

Microsoft.Exchange.WebServices.Data.ServiceResponseException:一个或多个收件人无效。

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

这是密码。没有比这更复杂的了。我通过改变
位置
主题
对其进行了测试,两者都会导致问题

Appointment a = Appointment.Bind(_service, new ItemId(id));
a.Location = newLocation
a.Update(ConflictResolutionMode.AlwaysOverwrite);
我是不是遗漏了什么概念?这似乎是一个相当严重的问题


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

我在这个问题的帮助下找到了答案:

关键是需要调用
Update
方法,并在第二个参数中设置
sendInvitationorCancellationMode.SendToNone
标志

像这样:

a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);

因此,当你不想向其他与会者发送约会更新时,tig的答案是有效的。但是,要正确回答这个问题,实际上需要加载与会者状态

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

  • AppointmentSchema.RequiredAttenders
  • AppointmentSchema.optionalAttenders
  • AppointSchema.Resources
  • AppointSchema.Organizer
如果要执行向与会者发送更新的更新,则此操作将填充与会者

然而,还有另一个边缘的情况,你必须担心。如果您的约会没有添加任何与会者(只有组织者),EWS可能仍会投诉并抛出此错误。在某些州,它实际上对任命有效,但在其他州则失败

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

  • 正在加载与会者状态
  • 检查与会者状态以查看除组织者之外是否还有其他与会者(取决于约会的创建方式,组织者可能会出现在RequiredAttenders集合中,也可能不会出现在其中)。如果没有,则必须使用SendInvitations或CancellationsMode.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;
    }
    

    来回答这个问题

    “即使我得到一个异常,该项目也会被保存并更改为 已将IsMeeting设置为true!现在更新的项目是具有 组织者等等……对我来说,这实际上是数据损坏。”

    Microsoft文档以小字体表示,“会议请求只是一个有与会者的约会。您可以通过向约会中添加所需的与会者、可选的与会者或资源,将约会转换为会议请求”-如图所示


    换句话说,只要您有任何与会者,Exchange就会自动将其转换为会议。

    此解决方案也适用于tig。我不明白为什么一个没有与会者的会议会抛出这个异常,不管你的解决方案如何有效。谢谢我给出了一个更完整的答案,解释了为什么会出现错误,以及如何进行更新以向与会者发送更新,而不是像此解决方案建议的那样从不发送更新。顺便说一句,另一个方向不成立。如果在EWS中召开会议并删除所有与会者,则会议不会转换回约会。
    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;
    }