.NET处理Exchange Server EWS托管API中的事件通知

时间:2016-03-09 15:15:52

标签: .net exchangewebservices exchange-server-2010 ews-managed-api

在EWS中处理NotificationEvents时,以下MSDN文档https://msdn.microsoft.com/en-us/library/office/hh312849(v=exchg.140).aspx由Henning Krause撰写。

显示了解决主题的两种不同方法,请参阅以下代码:

EX 1

private static void OnNotificationEvent(object sender, NotificationEventArgs args)
    {
        // Extract the item ids for all NewMail Events in the list.
        var newMails = from e in args.Events.OfType<ItemEvent>()
                       where e.EventType == EventType.NewMail
                       select e.ItemId;

        // Note: For the sake of simplicity, error handling is ommited here. 
        // Just assume everything went fine
        var response = _ExchangeService.BindToItems(newMails,
                                                    new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived,
                                                                    ItemSchema.Subject));
        var items = response.Select(itemResponse => itemResponse.Item);

        foreach (var item in items)
        {
            Console.Out.WriteLine("A new mail has been created. Received on {0}", item.DateTimeReceived);
            Console.Out.WriteLine("Subject: {0}", item.Subject);
        }
    }

    private static void OnSubscriptionError(object sender, SubscriptionErrorEventArgs args)
    {
        // Handle error conditions. 
        var e = args.Exception;
        Console.Out.WriteLine("The following error occured:");
        Console.Out.WriteLine(e.ToString());
        Console.Out.WriteLine();
    }


}

EX 2

private static void OnNotificationEvent(object sender, NotificationEventArgs args){
   foreach (var notification in args.Events){
      if (notification.EventType != EventType.NewMail) continue;
      Console.WriteLine("A new mail has been created");
      var itemEvent = (ItemEvent) notification;
      Console.WriteLine("The item ID of the new mail is {0}", itemEvent.ItemId.UniqueId);
   }
}

使用一种方法与另一种方法有什么区别/优势?

该示例仅显示如何处理1个特定的EventType,但在我的应用中,我实际上想知道何时和项目获得1.更新和2.已删除。

见下文:

Private Sub OnEvent(sender As System.Object, args As NotificationEventArgs)
    Dim oGuid As New Guid(DefaultExtendedPropertySet.PublicStrings)
    Dim oInternalContactId As New ExtendedPropertyDefinition(oGuid, conContactIdPropertyName, MapiPropertyType.Integer)
    Dim oDateAdded As New ExtendedPropertyDefinition(oGuid, conDteAddedPropertyName, MapiPropertyType.String)
    Dim oDateUpdated As New ExtendedPropertyDefinition(oGuid, conDteUpdatedPropertyName, MapiPropertyType.String)
    Dim lstUpdatedContactIds As New List(Of ItemId)
    Dim lstDeletedContactIds As New List(Of ItemId)
    Dim lstUpdatedContacts As New List(Of Contact)
    Dim lstDeletedContacts As New List(Of Contact)
    Dim oUpdatedContacts As ServiceResponseCollection(Of GetItemResponse)
    Dim oDeletedontacts As ServiceResponseCollection(Of GetItemResponse)
    Dim intInternalContactId As Integer

    lstUpdatedContactIds = From e In args.Events.OfType(Of ItemEvent)()
                           Where e.EventType = EventType.Modified
                           Select e.ItemId

    lstDeletedContactIds = From e In args.Events.OfType(Of ItemEvent)()
                           Where e.EventType = EventType.Deleted
                           Select e.EventType


    If lstUpdatedContactIds.Count > 0 Then
        oUpdatedContacts = args.Subscription.Service.BindToItems(lstUpdatedContactIds, New PropertySet(BasePropertySet.FirstClassProperties, oInternalContactId, oDateAdded, oDateUpdated))
        lstUpdatedContacts = oUpdatedContacts.Where(Function(collection) collection.Item.TryGetProperty(oInternalContactId, intInternalContactId))
    End If

    If lstDeletedContactIds.Count > 0 Then
        oDeletedontacts = args.Subscription.Service.BindToItems(lstDeletedContactIds, New PropertySet(BasePropertySet.FirstClassProperties, oInternalContactId, oDateAdded, oDateUpdated))
        lstDeletedContacts = oDeletedontacts.Where(Function(collection) collection.Item.TryGetProperty(oInternalContactId, intInternalContactId))
    End If

    Next
End Sub 

我是否按照EX 1中的方法进入了正确的轨道,或者我最好在EX 2之后离开?

如果每次捕获事件时OnNotificationEvent都会触发,为什么我们期望事件集合(EX 1)并使用LINQ,我们不应该期待单个事件吗?

Exchange如何处理多个连续的事件通知形成不同的邮箱它会自动对它们进行排队直到我们处理它们?

请记住,我同时监控了数百个邮箱。

谢谢!

1 个答案:

答案 0 :(得分:1)

正如您将会发现的那样,在Exchange中看起来像一个谨慎的行为,例如:创建一个新项目,通常会导致许多通知被传递给您的事件处理程序。现在我专门处理日历项目,自动接受的工作流程一直导致多个事件。使用收件箱中的标准电子邮件项目,我不确定会发生什么,但可能会有新的事件发生变化。根据我的经验,每个事件处理程序调用中的多个通知始终用于单个邮箱。

我没有完全区分EX1和EX2,但我鼓励你不要在事件处理程序中使用BindToItems。最好保存ItemIds和通知类型,并在另一个主线程上处理它们。与任何事件处理程序一样,您希望最小化您在那里的时间。

HTH