vb.net – 如何使用Exchange Web服务接受并向RequiredAttendees约会添加类别

我正在使用ExchangeService(ExchangeVersion.Exchange2010_SP1)

我想接受并将类别添加到RequiredAttendees约会.要做到这一点,我需要找到这些约会.

我在EWS中的理解是,在具有RequiredAttendees的预约中,为每个“必需参加者”创建了一个新的会议请求.

如何访问为“所需参加者”自动创建的约会?这些会在所需的与会者日历中显示为约会,以及会议请求.

我已成功对主题进行了粗略的查找(以下步骤)

>作为管理器连接到服务器
>创建约会
>设置主题
>添加所需的参加者
>保存约会
>从步骤4开始,按要求参加者连接到服务器
>在步骤3中找到具有主题的约会
>在步骤7中将类别添加到约会
>在步骤7更新约会
>在步骤7接受预约

这确实有效,但有关用户将更改主题.

我尝试将扩展属性和值添加到组织者创建的约会,然后将FindItems添加到作为必需参加者连接的约会中的扩展属性值.这不起作用.

对于我想要实现的目标,有一种首选方法吗?

谢谢

Private Shared ReadOnly m_organiserEmailAddress As String = "Organiser@test.com"
Private Shared ReadOnly m_eventIdExtendedPropertyDefinition As New ExtendedPropertyDefinition(DefaultExtendedPropertySet.Meeting, "EventId", MapiPropertyType.Long)

'--> start here
Public Shared Function SaveToOutlookCalendar(eventCalendarItem As EventCalendarItem) As String

    If eventCalendarItem.Id Is Nothing Then
        'new
        Dim newAppointment = EventCalendarItemMapper.SaveNewAppointment(eventCalendarItem)
        'set the Id
        eventCalendarItem.Id = newAppointment.Id.UniqueId.ToString()
        'accept the calendar item on behalf of the Attendee
        EventCalendarItemMapper.AcceptAppointmentAsAttendees(newAppointment)
        Return eventCalendarItem.Id
    Else
        'update existing appointment
        Return EventCalendarItemMapper.UpdateAppointment(eventCalendarItem)
    End If


End Function

Private Shared Sub ConnectToServer(Optional autoUser As String = "")

    If autoUser = "" Then
        _service.Url = New Uri(ExchangeWebServicesUrl)
    Else
        _service.AutodiscoverUrl(autoUser)
    End If

End Sub

Private Shared Sub ImpersonateUser(userEmail As String)

    _service.Credentials = New NetworkCredential(ImpersonatorUsername, ImpersonatorPassword, Domain)
    _service.ImpersonatedUserId = New ImpersonatedUserId(ConnectingIdType.SmtpAddress, userEmail)

End Sub

Private Shared Function SaveNewAppointment(eventCalendarItem As EventCalendarItem) As Appointment

    Try
        ConnectToServer(m_organiserEmailAddress)
        ImpersonateUser(m_organiserEmailAddress)

        Dim appointment As New Appointment(_service) With {
                   .Subject = eventCalendarItem.Subject}

        'add attendees
        For Each attendee In eventCalendarItem.Attendees
            appointment.RequiredAttendees.Add(attendee.Email)
        Next

        'add categories
        For Each category In eventCalendarItem.Categories
            appointment.Categories.Add(Globals.GetEnumDescription(category))
        Next

        'add EventId = 5059 as an extended property of the appointment
        appointment.SetExtendedProperty(m_eventIdExtendedPropertyDefinition, 5059)

        appointment.Save(SendInvitationsMode.SendOnlyToAll)

        Return appointment
    Catch
        Throw New Exception("Can't save appointment")
    End Try


End Function

Private Shared Sub AcceptAppointmentAsAttendees(appointment As Appointment)

    For Each attendee In appointment.RequiredAttendees
        Try
            ConnectToServer(attendee.Address.ToString())
            ImpersonateUser(attendee.Address.ToString())

            For Each a In FindRelatedAppiontments(appointment)
                a.Categories.Add(Globals.GetEnumDescription(CalendarItemCategory.Workshop))
                a.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone)
                a.Accept(True)
            Next

        Catch
            Throw
        End Try
    Next
End Sub

Private Shared Function FindRelatedAppiontments(appointment As Appointment) As List(Of Appointment)

    Dim view As New ItemView(1000)
    Dim foundAppointments As New List(Of Appointment)

    view.PropertySet =
        New PropertySet(New PropertyDefinitionBase() {m_eventIdExtendedPropertyDefinition})

    'Extended Property value = 5059
    Dim searchFilter = New SearchFilter.IsEqualTo(m_eventIdExtendedPropertyDefinition, 5059)

    For Each a In _service.FindItems(WellKnownFolderName.Calendar, searchFilter, view)
        If a.ExtendedProperties.Count > 0 Then
            foundAppointments.Add(appointment.Bind(_service, CType(a.Id, ItemId)))
        End If
    Next

    Return foundAppointments

End Function

最佳答案 有一点可以肯定的是,EWS没有任何直接的进展.

我会诚实地说,直到那一刻,我没有从内部日历到交换日历的整合工作,我的经验恰恰相反,这就是交换内部日历.

无论如何,在阅读完你的代码后,我认为你几乎就在那里.但是我建议您通过使用Streaming Notifications来捕捉到达与会者的约会并不难!
所以我会说步骤应该是这样的

>创建约会
>应用扩展属性(我建议使用GUID而不是硬编码),如下所示

创建一个扩展属性,并为指定添加guid,除非你从另一个约会制作一个副本(毕竟它只是一个属性),它不会改变

private static readonly PropertyDefinitionBase AppointementIdPropertyDefinition = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, "AppointmentID", MapiPropertyType.String);
public static PropertySet PropertySet = new PropertySet(BasePropertySet.FirstClassProperties, AppointementIdPropertyDefinition);


//Setting the property for the appointment 
 public static void SetGuidForAppointement(Appointment appointment)
{
    try
    {
        appointment.SetExtendedProperty((ExtendedPropertyDefinition)AppointementIdPropertyDefinition, Guid.NewGuid().ToString());
        appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendToNone);
    }
    catch (Exception ex)
    {
        // logging the exception
    }
}

//Getting the property for the appointment
 public static string GetGuidForAppointement(Appointment appointment)
{
    var result = "";
    try
    {
        appointment.Load(PropertySet);
        foreach (var extendedProperty in appointment.ExtendedProperties)
        {
            if (extendedProperty.PropertyDefinition.Name == "AppointmentID")
            {
                result = extendedProperty.Value.ToString();
            }
        }
    }
    catch (Exception ex)
    {
     // logging the exception
    }
    return result;
} 

>使用StreamingNotificationEvent捕获约会.在我看来,这样做的一个好方法是同时运行组织者和参加者,并抓住他们之间的约会.
为了看一个例子,我已经发布了上一个问题Multiple impersonation-threads in Exchange Web Service (EWS)的答案.如果您发现我的答案很有用,请投票支持这两个帖子的答案(在这里和那里).

我不想让你害怕,但一旦你解决了当前的问题;如果你想继续它会变得更复杂.我可以写下我如何解决会议问题,但我根本没有直接看到它,所以如果你自己编写它可能会更好.

干杯

点赞