c# - EWS 托管 API 流式通知...未通知使用 C# maildeleted 事件的 NewMail 观察程序

标签 c# ews-managed-api

将订阅流通知的 .Net 应用程序。这个应用程序运行良好,这个订阅在 30 mints 后断开连接,所以我添加了重新连接的代码。我通过在重新连接行添加断点来测试应用程序,并在它再次建立连接之前等待一段时间。在那段时间里,我创建了一些新电子邮件,并观察控制台是否显示这些事件。它没有,因为连接已断开,然后我再次运行代码,我能够看到在连接断开和连接期间创建的事件。我需要知道这是否是使此过程连续运行并跟踪在应用程序断开连接和重新连接期间发生的事件的正确方法。还需要知道为什么下面的代码没有通知删除邮件事件。请寻求帮助。

namespace NewMailNotification
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            //***********New**********************
            ExchangeService  mailbox = new ExchangeService(ExchangeVersion.Exchange2010_SP2); 
            string mailboxEmail = ConfigurationSettings.AppSettings["user-id"]; 
            WebCredentials wbcred = new WebCredentials(ConfigurationSettings.AppSettings["user"], ConfigurationSettings.AppSettings["PWD"]); 
            mailbox.Credentials = wbcred;
        //    mailbox.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxEmail);

            mailbox.AutodiscoverUrl(mailboxEmail, RedirectionUrlValidationCallback);
            mailbox.HttpHeaders.Add("X-AnchorMailBox", mailboxEmail);
            FolderId mb1Inbox = new FolderId(WellKnownFolderName.Inbox, mailboxEmail);
            SetStreamingNotification(mailbox, mb1Inbox);
            bool run = true;
            bool reconnect = false;
            while (run)
            {
                System.Threading.Thread.Sleep(100);
            }
        }

        internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
        {
            //The default for the validation callback is to reject the URL
            bool result=false;

            Uri redirectionUri=new Uri(redirectionUrl);
            if(redirectionUri.Scheme=="https")
            {
                result=true;
            }
            return result;
        }

        static void SetStreamingNotification(ExchangeService service,FolderId fldId)
        {
            StreamingSubscription streamingssubscription=service.SubscribeToStreamingNotifications(new FolderId[]{fldId},
                EventType.NewMail,
                EventType.Created,
                EventType.Deleted);

            StreamingSubscriptionConnection connection=new StreamingSubscriptionConnection(service,30);
            connection.AddSubscription(streamingssubscription);

            //Delagate event handlers
            connection.OnNotificationEvent+=new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
            connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(Connection_OnDisconnect);
            connection.OnSubscriptionError+=new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
            connection.Open();

        }

        static private void Connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
            if (!connection.IsOpen)             
            {
                //  Console.WriteLine("no connection");
                connection.Open();
            }
        }

        static void OnEvent(object sender,NotificationEventArgs args)
        {
            StreamingSubscription subscription=args.Subscription;
            if(subscription.Service.HttpHeaders.ContainsKey("X-AnchorMailBox"))
            {
                Console.WriteLine("event for nailbox"+subscription.Service.HttpHeaders["X-AnchorMailBox"]);
            }
            //loop through all the item-related events.
            foreach(NotificationEvent notification in args.Events)
            {
                switch(notification.EventType)
                {
                    case EventType.NewMail:
                        Console.WriteLine("\n----------------Mail Received-----");
                        break;
                    case EventType.Created:
                        Console.WriteLine("\n-------------Item or Folder deleted-------");
                        break;
                    case EventType.Deleted:
                        Console.WriteLine("\n------------Item or folder deleted---------");
                        break;

                }

                //Display notification identifier
                if(notification is ItemEvent)
                {
                    //The NotificationEvent for an email message is an ItemEvent
                    ItemEvent itemEvent=(ItemEvent)notification;
                    Console.WriteLine("\nItemId:"+ itemEvent.ItemId.UniqueId);
                    Item NewItem=Item.Bind(subscription.Service,itemEvent.ItemId);
                    if(NewItem is EmailMessage)
                    {
                        Console.WriteLine(NewItem.Subject);
                    }

                }
                else
                {
                    //the Notification for a Folder is an FolderEvent
                    FolderEvent folderEvent=(FolderEvent)notification;
                    Console.WriteLine("\nFolderId:"+folderEvent.FolderId.UniqueId);
                }
            }
        }
        static void OnError(object sender,SubscriptionErrorEventArgs args)
        {
            //Handle error conditions.
            Exception e=args.Exception;
            Console.WriteLine("\n-----Error-----"+e.Message+"--------");
        }
    }
}

最佳答案

这是一个例子:

       _BackroundSyncThread = new Thread(streamNotification.SynchronizeChangesPeriodically);       _BackroundSyncThread.Start();

 private void SynchronizeChangesPeriodically()
    {
      while (true)
      {
        try
        {
          // Get all changes from the server and process them according to the business
          // rules.
          SynchronizeChanges(new FolderId(WellKnownFolderName.Calendar));
        }
        catch (Exception ex)
        {
          Console.WriteLine("Failed to synchronize items. Error: {0}", ex);
        }
        // Since the SyncFolderItems operation is a 
        // rather expensive operation, only do this every 10 minutes
        Thread.Sleep(TimeSpan.FromMinutes(10));
      }
    }
    public void SynchronizeChanges(FolderId folderId)
    {
      bool moreChangesAvailable;
      do
      {
        Debug.WriteLine("Synchronizing changes...");
        // Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
        // Only the the ids are requested. Additional properties should be fetched via GetItem calls.
        var changes = _ExchangeService.SyncFolderItems(folderId, PropertySet.FirstClassProperties, null, 512,
                                                       SyncFolderItemsScope.NormalItems, _SynchronizationState);
        // Update the synchronization cookie
        _SynchronizationState = changes.SyncState;

        // Process all changes
        foreach (var itemChange in changes)
        {
          // This example just prints the ChangeType and ItemId to the console
          // LOB application would apply business rules to each item.
          Console.WriteLine("ChangeType = {0}", itemChange.ChangeType);
          Console.WriteLine("Subject = {0}", itemChange.Item.Subject);
        }
        // If more changes are available, issue additional SyncFolderItems requests.
        moreChangesAvailable = changes.MoreChangesAvailable;
      } while (moreChangesAvailable);
    }

_SynchronizationState 字段就像一个 Cookie,其中包含有关您上次同步过程的一些信息。所以下次线程将同步自上次同步以来的所有项目。 希望对你有帮助

关于c# - EWS 托管 API 流式通知...未通知使用 C# maildeleted 事件的 NewMail 观察程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28173488/

相关文章:

c# - 如何使用 EWS 托管 API 在 Exchange 2007 中获取项目 Web 客户端 ID

c# - 在asp.net mvc 5中创建可编辑的cshtml View 页面

c# - Exchange Web 服务托管 API : Accessing other users items

exchange-server - 交换 : Is it possible to search for a custom Extended Property across all mailboxes?

c# - 自定义下拉列表样式(CSS/JS 与 ASP.NET C# 连接)

exchange-server - 无法通过 Exchange 2007 SP1 上的 EWS 托管 API 检索 Appointment.StartTimeZone

calendar - EWS : Access shared calendars

c# - 如何在 VS Code 中将 .NET 项目设置为 StartUp?

java - 如何将 Java import 转换为 C# using 语句

c# - asp.net core 中的队列任务