Exchange摸拟用户和邮件提醒

本文主要介绍如何使用EWS托管API摸拟一个用户获取邮箱的信息,和如何使用流式订阅的方式获取邮箱通知信息。该方案只适用于Exchange 2010 SP1以上,Exchange 2013;

一、摸拟邮件用户登陆。

有些时候我们总不喜欢通过在应用程序中做一个弹出式的窗口,让用户输入邮箱的用户和密码才能获取此用户的邮箱信息;而且密码用户是随时自己可以更改的。弹出式的体验实在让用户觉得很差,我们的团队之前就是用这些方式做一些邮箱功能,有很多客户都说体验很差。这两天通过细读MSDN中的EWS API,不出我所料:像Win32通过Token摸拟Window用户一样,Exchange同样也能摸拟所有邮箱用户,以下是主要步骤。

1、新建一个普通的邮箱帐号作为服务帐号,本次使用的帐号是“management@toso.com

2、打开Exchange命令窗口并输入以下命令:

New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:management@toso.com

2、新建一条策略,基中1000表示取多可以同时摸拟10000个用户,ITUserPolicy表示的是策略的名字(值得注意的是后面的参数:-ThrottlingPolicyScope Regular,我在Exchange2010试过好像不支持:

Exchange2013:

New-ThrottlingPolicy -Name ITUserPolicy -EwsMaxConcurrency 10000 -ThrottlingPolicyScope Regular

Exchange 2010 SP1

New-ThrottlingPolicy -Name ITUserPolicy -EwsMaxConcurrency 10000

3、获取策略的GUID

Get-ThrottlingPolicy | format-list
然后复制对应ITUserPolic的GUID值  2a846f2b-75b1-4f26-be25-8f444e8a505c

4、将策略应用于基中management@toso.com
$a = Get-ThrottlingPolicyAssociation management@toso.com
$a | Set-ThrottlingPolicyAssociation -ThrottlingPolicy 2a846f2b-75b1-4f26-be25-8f444e8a505c

好的到现在为此,我的命令己经打完,接着我们的代码应该是这么写:

其中m_ServerUser为management@toso.com

m_Password是这个服务帐号的密码;

m_Domain是域名;

m_ExchangeMachine是EWS服务器。

strEmail是被摸拟的用户。

 

<p> string url = "<a target=_blank href="https://{0}/ews/exchange.asmx">https://{0}/ews/exchange.asmx</a>";
 url = string.Format(url, m_ExchangeMachine);
 ExchangeService _ExchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
 {
       Credentials = new NetworkCredential(m_ServerUser, m_Password, m_Domain),
       Url = new Uri(url)
 };</p><p><span style="color:#003300;">_ExchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, strEmail);</span></p>


二、邮件提醒

在Exchange 2007到Exchange 2010中,己经存在了两个邮箱订阅方式,分别是Pull Notification 和Push Noitification 这两种方式都有其中的优点和弱点,首先拿Push Notification来说,优点就是实时(Real Time)但缺点就需要我们提供一个端口,Exchange通过这个端口发送通知,Pull Notification不需要客户端(相对Exchange是服务)开通端口,但需要你定时去访问Exchange,失去实时性,到了Exchange 2010 Sp1,微软向我们提供了一个集两种方法优点的新的方案,流订阅方法(Streaming Subscription),以下是主要的源码片断:

 //创建订阅
RuleCollection ruleCollection = _ExchangeService.GetInboxRules();

 List<FolderId> lstfolder = new List<FolderId>();
 lstfolder.Add(new FolderId(WellKnownFolderName.Inbox));
foreach (Rule rule in ruleCollection)
 {
          if (rule.Actions != null && rule.Actions.MoveToFolder != null && rule.Actions.MoveToFolder.UniqueId != null)//过滤垃圾邮件规则
                     lstfolder.Add(rule.Actions.MoveToFolder.UniqueId);
 }
                    var subscription = _ExchangeService.SubscribeToStreamingNotifications(lstfolder.ToArray(), EventType.NewMail);

 

其中 CreateStreamingSubscription方法:

var connection = CreateStreamingSubscription(_ExchangeService, subscription);

 

        private 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;
        }

其实到现在为止,我己经介绍了机制,如果觉得烦的话,下面的内容可以不需要再看了;

 

以下是贴出我项目中的一些代码。

 

整个封装类的源码

 //新
    [XmlRoot("EmailNotification")]
    [Serializable]
    public class EmailNotification
    {

//邮件的主题
        [XmlElement("Subject")]
        public string Subject;

//邮件的创建者或发送者
        [XmlElement("Creator")]
        public string Creator;

//邮件内容的链接
        [XmlElement("Link")]
        public string Link;
        [XmlElement("CreatTime")]
        public string CreatTime;
        [XmlElement("Receipt")]
        public string Receipt;
    }


    public class EmailNotificationEventArgs : EventArgs
    {
        public EmailNotification Notification;
    }
    public class ExchSubscriptionClient
    {
        public delegate void (object sender, EmailNotificationEventArgs args);
        private class ExchClient
        {
            public ExchangeService _exch;
            public StreamingSubscriptionConnection conn;
            public StreamingSubscription subscription;
            public string user;
        }
        private Dictionary<string, ExchClient> m_lstEs = new Dictionary<string, ExchClient>();
        private Dictionary<StreamingSubscriptionConnection, ExchClient> m_conn_Ex = new Dictionary<StreamingSubscriptionConnection, ExchClient>();
        private static ExchSubscriptionClient g_instance = null;
        private string m_ServerUser;
        private string m_Password;
        private string m_Domain;
        private string m_ExchangeMachine;
        private bool m_IsInit;
        private object locker = new object();
        private ExchSubscriptionClient()
        {
            m_IsInit = false;
        }
        public static ExchSubscriptionClient Instance()
        {
            if (g_instance == null)
            {
                g_instance = new ExchSubscriptionClient();
            }
            return g_instance;
        }
        public event EmailNotificationDelegate NewEmailEvent;
        public bool IsInit()
        {
            return m_IsInit;
        }
        public void Init(string serverUser, string password, string domain, string exchFqdn)
        {
            m_ServerUser = serverUser;
            m_Password = password;
            m_Domain = domain;
            m_ExchangeMachine = exchFqdn;
            m_IsInit = true;
        }
        public void AddUser(string strEmail)
        {
            lock (locker)
            {
                try
                {
                    if (m_lstEs.ContainsKey(strEmail))
                    {
                        return;
                    }
                    string url = "https://{0}/ews/exchange.asmx";
                    url = string.Format(url, m_ExchangeMachine);
                    ExchangeService _ExchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
                    {
                        Credentials = new NetworkCredential(m_ServerUser, m_Password, m_Domain),
                        Url = new Uri(url)
                    };

                    _ExchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, strEmail);

                    //创建订阅
                    RuleCollection ruleCollection = _ExchangeService.GetInboxRules();

                    List<FolderId> lstfolder = new List<FolderId>();
                    lstfolder.Add(new FolderId(WellKnownFolderName.Inbox));
                    foreach (Rule rule in ruleCollection)
                    {
                        if (rule.Actions != null && rule.Actions.MoveToFolder != null && rule.Actions.MoveToFolder.UniqueId != null)//过滤垃圾邮件规则
                            lstfolder.Add(rule.Actions.MoveToFolder.UniqueId);
                    }
                    var subscription = _ExchangeService.SubscribeToStreamingNotifications(lstfolder.ToArray(), EventType.NewMail);

                    var connection = CreateStreamingSubscription(_ExchangeService, subscription);

                    ExchClient client = new ExchClient();
                    client._exch = _ExchangeService;
                    client.conn = connection;
                    client.user = strEmail;
                    client.subscription = subscription;
                    m_lstEs.Add(strEmail, client);
                    m_conn_Ex.Add(connection, client);
                }
                catch (Exception ex)
                {

                }
            }
        }
        public void RemoveUser(string strEmail)
        {
            lock (locker)
            {
                ExchClient client = m_lstEs[strEmail];
                if (client != null)
                {
                    try
                    {
                        client.subscription.Unsubscribe();
                        client.conn.Close();
                        m_conn_Ex.Remove(client.conn);
                        m_lstEs.Remove(strEmail);
                    }
                    catch
                    {
                    }
                }
            }

        }
        private 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 void OnDisconnect(object sender, SubscriptionErrorEventArgs args)
        {
            // Cast the sender as a StreamingSubscriptionConnection object.          
            var connection = (StreamingSubscriptionConnection)sender;
            try
            {
                connection.Open();
            }
            catch
            {
                lock (locker)
                {
                    string strEmail = m_conn_Ex[connection].user;
                    m_conn_Ex.Remove(connection);
                    m_lstEs.Remove(strEmail);
                }
            }

        }

        private void OnNotificationEvent(object sender, NotificationEventArgs args)
        {
            if (NewEmailEvent == null)
                return;
            // 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
            StreamingSubscriptionConnection conn = sender as StreamingSubscriptionConnection;
            ExchangeService es = null;
            ExchClient client = m_conn_Ex[conn];
            if (client != null)
                es = client._exch;
            if (es == null)
                return;
            var response = es.BindToItems(newMails, new PropertySet(BasePropertySet.IdOnly, ItemSchema.DateTimeReceived, ItemSchema.Subject, ItemSchema.LastModifiedName, ItemSchema.WebClientReadFormQueryString));
            var items = response.Select(itemResponse => itemResponse.Item);
            foreach (var item in items)
            {
                EmailNotificationEventArgs e = new EmailNotificationEventArgs();
                EmailNotification emailNotification = new EmailNotification();

                //string owaUrl = "https://{0}/owa/";
                //owaUrl = string.Format(owaUrl, ExchSubscriptionClient.Instance().m_ExchangeMachine);
                emailNotification.Subject = string.IsNullOrEmpty(item.Subject) ? "无标题邮件" : item.Subject;
                //emailNotification.Link = owaUrl + item.WebClientReadFormQueryString;
                emailNotification.Link = item.WebClientReadFormQueryString;
                emailNotification.CreatTime = item.DateTimeReceived.ToString();
                emailNotification.Creator = item.LastModifiedName;
                emailNotification.Receipt =  + client.user;
                e.Notification = emailNotification;

                NewEmailEvent(this, e);
            }

        }

        private void OnSubscriptionError(object sender, SubscriptionErrorEventArgs args)
        {
            // Handle error conditions.
            var e = args.Exception;

            //写入日志

        }

 

客户代码(以上类的客户)

  ExchSubscriptionClient es=ExchSubscriptionClient.Instance();
  if (!es.IsInit())
  {
          es.Init(ConfigHelper.ServerUser, ConfigHelper.Password, ConfigHelper.Domain, ConfigHelper.ExchangeFQDN);
          es.NewEmailEvent += new ExchSubscriptionClient.EmailNotificationDelegate(es_NewEmailEvent);
  }
   es.AddUser(hejg@toso.com);

 

 

 

      

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值