65.9K
CodeProject 正在变化。 阅读更多。
Home

EWS 邮件通知器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (4投票s)

2010 年 4 月 19 日

CPOL

2分钟阅读

viewsIcon

75637

downloadIcon

3015

适用于 Exchange 的简单邮件通知器

引言

最近我一直在做一个项目,该项目是一个Exchange 2010的实时新邮件通知器。为此,我使用了Exchange Web Services API,以及我们的朋友Rodolfo Ortega在CodeProject上提供的web 服务器骨架

要求

工作原理?

该程序通过EWS API创建一个推送订阅,然后,我使用web服务器骨架来监听Exchange发送的SOAP消息。为了反序列化Exchange在SOAP消息中包含的通知,我需要从Exchange的模式文件生成类,然后,我使用WSE 3.0来反序列化SOAP消息。

生成类

为了生成用于反序列化Exchange通知的类,我们将使用位于服务器EWS目录中的“messages.xsd”和“types.xsd”模式文件

xsd /c /language:CS /namespace:EWSConsoleNotify messages.xsd types.xsd 

反序列化Exchange SOAP消息

为了反序列化Exchange发送并通过我们的web服务器骨架接收的SOAP消息,我们将使用WSE通过将XML消息传递给序列化器来反序列化它

SoapEnvelope soapEnvelope = new SoapEnvelope();
                   
soapEnvelope.InnerXml = Body;
           
Type type = typeof(SendNotificationResponseType);

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "SendNotification";
xRoot.Namespace = "http://schemas.microsoft.com/exchange/services/2006/messages";
XmlSerializer serializer = new XmlSerializer(type, xRoot);
XmlNodeReader reader = new XmlNodeReader(soapEnvelope.Body.FirstChild);

SendNotificationResponseType obj = 
	(SendNotificationResponseType)serializer.Deserialize(reader);

处理Exchange通知

一旦我们有了反序列化的消息,此方法将处理SOAP消息中包含的所有通知。请注意,在循环内部,我只检查新邮件事件,因为Exchange还会发送“Status”消息

    public SendNotificationResultType ProcessNotification
		(SendNotificationResponseType SendNotification)
    {          
        SendNotificationResultType result = 
		new SendNotificationResultType(); // Notification's result
        bool unsubscribe = false; 
        ResponseMessageType[] responseMessages = 
		SendNotification.ResponseMessages.Items; // Response messages
        foreach (ResponseMessageType responseMessage in responseMessages)
        {
            if (responseMessage.ResponseCode != ResponseCodeType.NoError)
            {
                
                result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
                return result;
            }
            NotificationType notification = 
		((SendNotificationResponseMessageType)responseMessage).Notification;
            string subscriptionId = notification.SubscriptionId;
          
            // If subscription Id is not the current subscription Id, unsubscribe
            if (subscriptionId != _parent.SubscriptionId)
            {
                unsubscribe = true;
            }
            else
            {
                for (int c = 0; c < notification.Items.Length; c++)
                {
                    // Get only new mail events
                    if (notification.ItemsElementName[c].ToString() == "NewMailEvent")
                    {
                        BaseObjectChangedEventType bocet = 
			(BaseObjectChangedEventType)notification.Items[c];
                        _parent.ShowMessage(((ItemIdType)bocet.Item).Id);
                    }
                }
            }           
        }
        if (unsubscribe)
        {
            result.SubscriptionStatus = SubscriptionStatusType.Unsubscribe;
        }
        else
        {
            result.SubscriptionStatus = SubscriptionStatusType.OK;
        }
        return result;
    }
}        

使用EWS API创建推送通知的订阅

此方法创建推送订阅,并启动带有我们的web服务器骨架的线程以监听传入连接

public void Start()
{
    System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate(
        Object obj,
        X509Certificate certificate,
        X509Chain chain,
        SslPolicyErrors errors)
    {
        return true;
        // TODO: check for a valid certificate
    };
    
    // Create the subscription
    _service = new ExchangeService();
    // Set credentials: user, password and domain
    _service.Credentials = new WebCredentials("user", "password", "domain");
    // URL of the EWS
    _service.Url = new Uri("https://exchange_server/ews/exchange.asmx");
    
    PushSubscription ps = 
      _service.SubscribeToPushNotificationsOnAllFolders(new Uri("http://your_IP:5050"),
        5 // Every 5 minutes Exchange will send us a status message
        , null, EventType.NewMail);
        
    SubscriptionId = ps.Id;
    
    // Listen on port 5050
    _listener = new TcpListener(5050);
    _listener.Start();
    
    _th = new Thread(new ThreadStart(ProcessIncomingMessages));
    _th.Start();
    
    WriteLog("Listening for incoming messages...");
}

显示接收到的新邮件

要显示接收到的新邮件,我们需要绑定到通知中发送的项目Id

public void ShowMessage(string UniqueId)
{
    EmailMessage mail = ((EmailMessage)Item.Bind(_service, new ItemId(UniqueId)));

    Console.WriteLine("New mail from: {0}, Subject: {1}", mail.From.Name, mail.Subject);
}

屏幕截图

screenshot.jpg

备注

此示例在Exchange 2010上进行了测试,我不知道它是否适用于早期版本。可能需要使用WCF来实现,但在我进行的测试中,它对我不起作用,因此我使用了Rodolfo的web服务器骨架来监听Exchange发送的SOAP消息。

我希望这个示例能帮助你。;-)

推荐链接

© . All rights reserved.