asp.net – 适用于多个用户的EWS通知中心
我正在尝试创建一个服务来将交换通知推送到asp.net应用程序,最终使用SignalR.
我的计划是创建一个通知中心,在每个用户登录到asp应用程序时为其预订,并为他们监听通知.当收到通知时,项目的第二部分是使用signalR仅向每个用户发送正确的通知.一旦他们注销或超时,通知中心将取消订阅. 到目前为止,我已经完成了一些基本的测试,并且可以通过我的凭证硬编码在一个小的控制台应用程序中接收通知.我正在努力的是如何同时为多个人这样做.例如,我是否必须为每个用户创建单独的线程,还是有更好的方法? 我想无论我不得不使用模仿而不是持有每个用户的凭据吗?如果每个用户都有活动会话,我还必须找到一种自动刷新超时的方法. 下面是我发现并且一直在玩的一些代码,我将很感激任何想法或任何人可以分享我如何能够最好地实现这一目标的例子. 非常感谢 安迪 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Threading.Tasks; using Microsoft.Exchange.WebServices.Data; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2); service.Url = new Uri("https://server/EWS/Exchange.asmx"); service.Credentials = new NetworkCredential("user","pass","domain"); SetStreamingNotifications(service); while (true) { } } static void SetStreamingNotifications(ExchangeService service) { // Subscribe to streaming notifications on the Inbox folder,and listen // for "NewMail","Created",and "Deleted" events. StreamingSubscription streamingsubscription = service.SubscribeToStreamingNotifications( new FolderId[] { WellKnownFolderName.Calendar,WellKnownFolderName.Inbox },EventType.Created,EventType.Modified); StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(service,9); connection.AddSubscription(streamingsubscription); // Delegate event handlers. connection.OnNotificationEvent += new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent); connection.OnSubscriptionError += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError); connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect); connection.Open(); Console.WriteLine("--------- StreamSubscription event -------"); } static private void OnDisconnect(object sender,SubscriptionErrorEventArgs args) { // Cast the sender as a StreamingSubscriptionConnection object. StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender; // Ask the user if they want to reconnect or close the subscription. ConsoleKeyInfo cki; Console.WriteLine("The connection to the subscription is disconnected."); Console.WriteLine("Do you want to reconnect to the subscription? Y/N"); while (true) { cki = Console.ReadKey(true); { if (cki.Key == ConsoleKey.Y) { connection.Open(); Console.WriteLine("Connection open."); break; } else if (cki.Key == ConsoleKey.N) { // The ReadKey in the Main() consumes the E. Console.WriteLine("nnPress E to exit"); break; } } } } static void OnEvent(object sender,NotificationEventArgs args) { StreamingSubscription subscription = args.Subscription; // Loop through all item-related events. foreach (NotificationEvent notification in args.Events) { switch (notification.EventType) { case EventType.NewMail: Console.WriteLine("n-------------Mail created:-------------"); break; case EventType.Created: Console.WriteLine("n-------------Item or folder created:-------------"); break; case EventType.Deleted: Console.WriteLine("n-------------Item or folder deleted:-------------"); break; } // Display the notification identifier. if (notification is ItemEvent) { // The NotificationEvent for an e-mail message is an ItemEvent. ItemEvent itemEvent = (ItemEvent)notification; Console.WriteLine("nItemId: " + itemEvent.ItemId.UniqueId); } else { // The NotificationEvent 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 + "-------------"); } } } 解决方法
我解决这个问题的方法是:
>拥有一个有权冒充所有用户的帐户. 这是我的代码的两个部分.忘记LogDevice它只是内部的东西. /// <summary> /// Impersonate one user at a time and without using the autodiscovery method to find the proper url for the userSmtp,/// and copy the provided url to the usersmtp. /// </summary> /// <param name="url"> </param> /// <param name="userSmtp">user smtp</param> /// <param name="enableTrace">to enable logging from the XML tracing </param> /// <param name="exchangeVersion">Exchange server version used</param> private Uri ImpersonateUser(Uri url,string userSmtp,bool enableTrace,ExchangeVersion exchangeVersion) { Uri result = url; var log = "ImpersonateUser n"; try { log += "0/8 Checking services redundancyn"; if (Services.ContainsKey(userSmtp)) { Services.Remove(userSmtp); } log += "1/8 Create a new service for " + userSmtp + "n"; var service = new ExchangeService(exchangeVersion); log += "2/8 Get credentials for the servicen"; var serviceCred = ((System.Net.NetworkCredential)(((WebCredentials)(Services.First().Value.Credentials)).Credentials)); log += "3/8 Assign credentials to the new servicen"; service.Credentials = new WebCredentials(serviceCred.UserName,serviceCred.Password); log += "4/8 TraceEnabled is" + enableTrace.ToString() + "n"; service.TraceEnabled = enableTrace; log += "5/8 Get the Url for the service with AutodiscoverUrl n"; service.Url = url; log += "6/8 Assign a new ImpersonatedUserId to the new service for" + userSmtp + "n"; service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,userSmtp); try { log += "7/8 Validating the impersonationn"; RuleCollection rulecoll = service.GetInboxRules(); } catch (Exception ex) { _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser: failed to validate the impersonation for {0}n Exception: {1}n",userSmtp,ex.Message); int hr = System.Runtime.InteropServices.Marshal.GetHRForException(ex); if (hr == -2146233088) // We do not have right to impersonate this user. { result = null; return result; } else { _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): trying to resolve {0} with Autodiscover instead...",userSmtp); result = ImpersonateUser(userSmtp,enableTrace,exchangeVersion); } } log += "8/8 Adding the service n"; if (!Services.ContainsKey(userSmtp)) { Services.Add(userSmtp,service); _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): {0} has been impersonatedn",service.ImpersonatedUserId.Id); } } catch (Exception ex) { _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): exception {0}n The exception occured after the following steps: n{1}",ex.Message,log); } return result; } 以下是调用上一个函数(即对所有用户)的代码,请记住,您应该以某种方式存储要模拟的每个帐户的电子邮件地址. /// <summary> /// To Impersonate users in order to get the info from them. /// </summary> /// <param name="userSmtps">List of users to be impersonated</param> /// <param name="enableTrace"> To enable logging from the XML tracing</param> /// <param name="exchangeVersion">Exchange server version used </param> public void ImpersonateUsers(ICollection<string> userSmtps) { var log = "ImpersonateUsersn"; var firstUserSmtp = ""; if (userSmtps != null) if (userSmtps.Count > 0) { //the url for the first smtp try { log += "1/2 Impersonating the first userSmtpn"; _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: Getting the Url from the autodiscovery for the first smtp {0} ",userSmtps.First()); bool enableTrace = Services.First().Value.TraceEnabled; ExchangeVersion exchangeVersion = Services.First().Value.RequestedServerVersion; firstUserSmtp = userSmtps.First(); var commonSmtpUrl = ImpersonateUser(userSmtps.First(),exchangeVersion); if (commonSmtpUrl == null) userSmtps.Remove(firstUserSmtp); // If the list contains other than the first one log += "2/2 Impersonating " + (userSmtps.Count - 1) + " userSmtpsn"; if (userSmtps.Count >= 1) { foreach (var userSmtp in userSmtps) { try { //skip ther first one because it is already impersonated. if (userSmtp == firstUserSmtp) { continue; } // Impersonate the users _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: Impersonating {0} ...",userSmtp); commonSmtpUrl = ImpersonateUser(userSmtp,exchangeVersion); } catch (Exception ex) { _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: Impersonating {1}n exception {0}n",userSmtp); } } } } catch (Exception ex) { _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: exception {0}n The exception occured after the following steps: n{1}",log); } } } 我会把订阅部分和添加到连接,但它有点难看,很难得到.但想法只是你应该有一个连接,然后你去你做的每个服务,然后`connection.AddSubscription(streamingSubscription);其中streamingSubscription是从服务中提取的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-core – 来自带有Entity Framework Core的Data Tie
- C#_.NetCore_WebAPI项目_EXCEL数据导出(ExcelHelper_第二版
- 在ASP.Net图表控件上隐藏网格线
- 是否可以更改ASP.NET MVC 3路由约束,以便它们返回带有JSON主
- asp.net – 来自masterpage的Html.RenderPartial调用
- asp.net – DropDownList的EditorTemplate
- asp.net-mvc – 未找到或构造错误的路由
- asp.net – 微软的AJAX Toolkit与jQuery
- asp.net – ASP Core,Identity Server 4和Angular 2中的外部
- asp.net – IItemTransform和现有的缩小文件
- asp.net – 页面上有多个RequiredFieldValidator
- asp.net – 在.aspx页面上显示图像的字节
- ASP.NET优化不会将LESS转换为CSS
- asp.net-mvc – 已定义以下部分但尚未为布局页面
- asp.net-mvc-2 – ASP.NET-MVC2预览1:有任何重大
- asp.net – 如何在Web.config中启用SmtpClient的
- ASP.NET AJAX日历扩展程序日期格式
- asp.net-mvc-3 – MVC EditorFor命名模板的问题
- asp.net – MVC控制器和视图应该有1到1的关系吗?
- asp.net-mvc – 实体框架 – 选择特定列并返回强