在ASP.NET MVC中使用EWS Managed API

时间:2014-12-22 23:21:42

标签: c# asp.net-mvc-4 exchange-server exchangewebservices

我正在尝试创建一个可以执行许多操作的Web应用程序,但我目前关注的是收件箱数量。我想使用EWS StreamSubscription,以便我可以获取每个事件的通知并返回收件箱中的项目总数。我如何在MVC方面使用它?我确实找到了一些我将要测试的Microsoft教程中的代码,但我无法想象如何在MVC世界中使用它,即模型是什么,如果模型是计数,那么每次都会得到通知Exchange Server等中发生事件。

这是我从Microsoft下载的代码,但是我无法理解如何将计数转换为json并在新的更改事件发生时立即将其推送到客户端。注意:此代码未更改,因此它不会返回计数。

using System;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.Exchange.WebServices.Data;

namespace StreamingNotificationsSample
{
    internal class Program
    {
        private static AutoResetEvent _Signal;
        private static ExchangeService _ExchangeService;
        private static string _SynchronizationState;
        private static Thread _BackroundSyncThread;

        private static StreamingSubscriptionConnection CreateStreamingSubscription(ExchangeService service,
                                                                                   StreamingSubscription subscription)
        {
            var connection = new StreamingSubscriptionConnection(service, 30);
            connection.AddSubscription(subscription);
            connection.OnNotificationEvent += OnNotificationEvent;
            connection.OnSubscriptionError += OnSubscriptionError;
            connection.OnDisconnect += OnDisconnect;
            connection.Open();

            return connection;
        }

        private static void SynchronizeChangesPeriodically()
        {
            while (true)
            {
                try
                {
                    // Get all changes from the server and process them according to the business
                    // rules.
                    SynchronizeChanges(new FolderId(WellKnownFolderName.Inbox));
                }
                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 static void SynchronizeChanges(FolderId folderId)
        {
            bool moreChangesAvailable;
            do
            {
                Console.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.IdOnly, 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.Out.WriteLine("ChangeType = {0}", itemChange.ChangeType);
                    Console.Out.WriteLine("ChangeType = {0}", itemChange.ItemId);
                }
                // If more changes are available, issue additional SyncFolderItems requests.
                moreChangesAvailable = changes.MoreChangesAvailable;
            } while (moreChangesAvailable);
        }


        public static void Main(string[] args)
        {
            // Create new exchange service binding
            // Important point: Specify Exchange 2010 with SP1 as the requested version.
            _ExchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
                               {
                                Credentials = new NetworkCredential("user", "password"),
                                Url = new Uri("URL to the Exchange Web Services")
                               };

            // Process all items in the folder on a background-thread.
            // A real-world LOB application would retrieve the last synchronization state first 
            // and write it to the _SynchronizationState field.
            _BackroundSyncThread = new Thread(SynchronizeChangesPeriodically);
            _BackroundSyncThread.Start();

            // Create a new subscription
            var subscription = _ExchangeService.SubscribeToStreamingNotifications(new FolderId[] {WellKnownFolderName.Inbox},
                                                                                  EventType.NewMail);
            // Create new streaming notification conection
            var connection = CreateStreamingSubscription(_ExchangeService, subscription);

            Console.Out.WriteLine("Subscription created.");
            _Signal = new AutoResetEvent(false);

            // Wait for the application to exit
            _Signal.WaitOne();

            // Finally, unsubscribe from the Exchange server
            subscription.Unsubscribe();
            // Close the connection
            connection.Close();
        }

        private static void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            // Cast the sender as a StreamingSubscriptionConnection object.           
            var connection = (StreamingSubscriptionConnection) sender;
            // Ask the user if they want to reconnect or close the subscription. 
            Console.WriteLine("The connection has been aborted; probably because it timed out.");
            Console.WriteLine("Do you want to reconnect to the subscription? Y/N");
            while (true)
            {
                var keyInfo = Console.ReadKey(true);
                {
                    switch (keyInfo.Key)
                    {
                        case ConsoleKey.Y:
                            // Reconnect the connection
                            connection.Open();
                            Console.WriteLine("Connection has been reopened.");
                            break;
                        case ConsoleKey.N:
                            // Signal the main thread to exit.
                            Console.WriteLine("Terminating.");
                            _Signal.Set();
                            break;
                    }
                }
            }
        }

        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();
        }
    }
}

我只是想了解基本概念,因为什么是模型,我在哪里可以使用其他功能。

2 个答案:

答案 0 :(得分:1)

您的问题是您将服务(EWS)与应用程序模型混淆。他们是两个不同的东西。您的模型完全由您控制,您可以随心所欲地执行任何操作。 EWS不受您的控制,只是您调用以获取数据的服务。

在您的控制器中,您呼叫EWS服务并获取计数。然后使用该计数填充模型,然后在视图中渲染该模型属性。它真的很简单。

网页没有状态。当事情发生变化时,它不会收到通知。您只需重新加载页面并获取当前状态(即,无论当前计数是什么)。

在更高级的应用程序中,例如使用Ajax的单页应用程序,您可以在后台定期查询服务。或者,您可能有一个特殊的通知服务,它使用SignalR之类的东西来通知您的SPA更改,但这些概念远比您目前更先进。您可能应该首先将您的应用程序开发为一个简单的无状态应用程序,然后改进它以添加ajax功能,或者一旦您更好地掌握了这些功能。

答案 1 :(得分:0)

这是一个非常广泛的问题,没有明确的答案。您的模型当然可以具有可以更新的“计数”属性。您找到的示例代码可能会被您的控制器使用。