C# 是否使用Exchange Web服务管理的API检测电子邮件移动?

C# 是否使用Exchange Web服务管理的API检测电子邮件移动?,c#,exchangewebservices,ews-managed-api,C#,Exchangewebservices,Ews Managed Api,我正在使用EWS管理的API和C 我想知道是否有可能检测到电子邮件何时移动到另一个文件夹 这就是我到目前为止所做的: static void SetPullNotifications(ExchangeService service) { PullSubscription subscription = service.SubscribeToPullNotificationsOnAllFolders( 5, null, EventType.Moved, EventT

我正在使用EWS管理的API和C

我想知道是否有可能检测到电子邮件何时移动到另一个文件夹

这就是我到目前为止所做的:

static void SetPullNotifications(ExchangeService service)
{

    PullSubscription subscription = service.SubscribeToPullNotificationsOnAllFolders(
      5, null,
      EventType.Moved, EventType.Deleted, EventType.Copied, EventType.Modified);

    GetEventsResults events = subscription.GetEvents();

    foreach (ItemEvent itemEvent in events)
    {
        switch (itemEvent.EventType)
        {
            case EventType.Moved:
                MessageBox.Show("Item Moved :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Deleted:
                MessageBox.Show("Item deleted: " + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Copied:
                MessageBox.Show("Item Copied :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Modified:
                MessageBox.Show("Item Modified :" + itemEvent.ItemId.UniqueId);
                break;
        }
    }
}
如果我在方法
GetEvents()
上放置一个断点,然后移动一封电子邮件,这就可以了。但如果没有断点,它将无法工作。
事件
不包含任何结果


有什么想法吗?

您可以使用EWS的流式通知来侦听Exchange服务器上项目的更改。以下是有关如何设置流式通知的示例:


在你的情况下,你应该处理这个事件。在处理事件时,系统会为您提供一个类型为的对象(如上例所示),该对象具有两个属性,用于标识项目从哪个文件夹移动到哪个文件夹。

您可以使用EWS的流式通知来侦听Exchange Server上项目的更改。以下是有关如何设置流式通知的示例:


在你的情况下,你应该处理这个事件。处理事件时,会给您一个类型为的对象(如上例所示),该对象有两个属性,用于标识项目从哪个文件夹移动到哪个文件夹。

您的方法是正确的,但您缺少了一些东西。您的代码将只获取在创建订阅和获取事件之间发生的事件,这就是为什么它只使用断点

要使代码正常工作,您应该做两件事。 首先:在启动应用程序时创建子选项,并对其进行引用。 在第二个存储从订阅中获得的水印,并在应用程序启动时重新加载它。也许是这样:

static PullSubscription s_Subscription;

static void Main()
{
    ExchangeService service = CreateService();
    CreateSubsciption(service);
    //DoSomething;
    GetEvents();
    //DoSomething;
    StoreWatermark(s_Subscription.Watermark);
}

static void CreateSubscription(ExchangeService Service)
{
    string watermarkt = LoadWatermark(); 
    s_Subscription = service.SubscribeToPullNotificationsOnAllFolders(
        5, watermark,
        EventType.Moved, EventType.Deleted, EventType.Copied, EventType.Modified);

}

static void GetEvents()
{

    GetEventsResults events = subscription.GetEvents();

    foreach (ItemEvent itemEvent in events)
    {
        switch (itemEvent.EventType)
        {
            case EventType.Moved:
                MessageBox.Show("Item Moved :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Deleted:
                MessageBox.Show("Item deleted: " + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Copied:
                MessageBox.Show("Item Copied :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Modified:
                MessageBox.Show("Item Modified :" + itemEvent.ItemId.UniqueId);
                break;

        }
    }
}

你在正确的道路上,但你错过了一些东西。您的代码将只获取在创建订阅和获取事件之间发生的事件,这就是为什么它只使用断点

要使代码正常工作,您应该做两件事。 首先:在启动应用程序时创建子选项,并对其进行引用。 在第二个存储从订阅中获得的水印,并在应用程序启动时重新加载它。也许是这样:

static PullSubscription s_Subscription;

static void Main()
{
    ExchangeService service = CreateService();
    CreateSubsciption(service);
    //DoSomething;
    GetEvents();
    //DoSomething;
    StoreWatermark(s_Subscription.Watermark);
}

static void CreateSubscription(ExchangeService Service)
{
    string watermarkt = LoadWatermark(); 
    s_Subscription = service.SubscribeToPullNotificationsOnAllFolders(
        5, watermark,
        EventType.Moved, EventType.Deleted, EventType.Copied, EventType.Modified);

}

static void GetEvents()
{

    GetEventsResults events = subscription.GetEvents();

    foreach (ItemEvent itemEvent in events)
    {
        switch (itemEvent.EventType)
        {
            case EventType.Moved:
                MessageBox.Show("Item Moved :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Deleted:
                MessageBox.Show("Item deleted: " + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Copied:
                MessageBox.Show("Item Copied :" + itemEvent.ItemId.UniqueId);
                break;
            case EventType.Modified:
                MessageBox.Show("Item Modified :" + itemEvent.ItemId.UniqueId);
                break;

        }
    }
}

你的代码不起作用的原因很简单。没有时间让事情发生。您创建了一个子描述,它将只识别从您创建它的那一刻起的事件,因为水印为空。只有一行之后,比如说一毫秒之后,你问订阅“嘿,在过去的毫秒里有什么事件吗?”答案是“没有”。在程序启动时创建订阅并在计时器上调用getevents,可能5分钟后。如果您在过去五分钟内发生了任何事件,您的消息框就会出现。

原因很简单,您的代码无法工作。没有时间让事情发生。您创建了一个子描述,它将只识别从您创建它的那一刻起的事件,因为水印为空。只有一行之后,比如说一毫秒之后,你问订阅“嘿,在过去的毫秒里有什么事件吗?”答案是“没有”。在程序启动时创建订阅并在计时器上调用getevents,可能5分钟后。如果您在过去五分钟内发生任何事件,您的消息框将出现。

谢谢您的回答。不幸的是,我使用的是ExchangeService2010而不是SP1。我尝试了类似的方法,但使用了“PullSubscription”,但当我尝试使用“GetEvents()”时,我发现nothing@StephaneBintein:我和你一样使用PullSubscriptions,一切正常。您必须获得邮箱中所有文件夹的列表。而且比它好用。您的代码应该如下所示:List folders=getAllFolderId();订阅=service.SubscribeToPullNotifications(文件夹,1440,水印,EventType.Moved);GetEventsResults currentevents=Subscription.GetEvents();如果邮件在您的订阅和调用GetEvents()之间移动,则移动将包括在内。@Jürgenhofmann:我认为您应该添加您的评论作为答案,以便OP可以将其标记为正确答案。谢谢您的回答。不幸的是,我使用的是ExchangeService2010而不是SP1。我尝试了类似的方法,但使用了“PullSubscription”,但当我尝试使用“GetEvents()”时,我发现nothing@StephaneBintein:我和你一样使用PullSubscriptions,一切正常。您必须获得邮箱中所有文件夹的列表。而且比它好用。您的代码应该如下所示:List folders=getAllFolderId();订阅=service.SubscribeToPullNotifications(文件夹,1440,水印,EventType.Moved);GetEventsResults currentevents=Subscription.GetEvents();如果邮件在订阅和调用GetEvents()之间移动,则移动将包括在内。@Jürgenhofmann:我认为您应该添加您的评论作为答案,以便OP可以将其标记为正确答案。