基于OWA方式获取Exchange中未读邮件

http://www.cnblogs.com/jinho/archive/2011/09/17/2179819.html

有些项目中, 需要获取获取未读邮件数量, 比如在sharepoint项目中, 需要一个webpart来展示未读邮件. 做这个事情呢, 我也是第一次,之前连OWA,WebDAV是玩意也不知道是个什么东西.

当然还是借助强大的网络了, 网上其实很多人做个这个东西,多数都是一样,大多转载别人的(很多有注明地址.) 下面主要先贴出主要代码, 其实主要代码也不是我写的, 都是网上分享的. 只说说我期间遇到的一些问题.

code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Configuration;

using Microsoft.SharePoint;

using Microsoft.SharePoint.Administration;
///这里你需要添加web引用;ExchangeServiceBinding
using CompanyName.App.net.mail;



namespace CompanyName.App

{

    /// <summary>

    /// GetUnReadEmailCountHandler 的摘要说明

    /// </summary>

    public class GetUnReadEmailCountHandler : IHttpHandler

    {



        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentType = "text/plain";

            string unRead = "-1";

            try

            {

                unRead = @"<a href=""" + ConfigurationManager.AppSettings["MailServer"] + @""" target=""_blank"">" + GetUnreadMailCount().ToString() + "</a>";

            }

            catch (Exception ex)

            {

                ///写入错误日志

                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("读取邮件出错", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);

            }

            context.Response.Write(unRead);

        }



        public bool IsReusable

        {

            get

            {

                return false;

            }

        }



        



        protected int GetUnreadMailCount()

        {



            try

            {

                string connectionString = System.Configuration.ConfigurationManager.AppSettings["ExchangeContext"];



                int unreadCount = 0;



               ///绑定exchange服务器 这里你需要添加web引用,https://mail.Address.com/EWS/Exchange.asmx 

               ExchangeServiceBinding exchangeServer = new ExchangeServiceBinding();

               ///下面这句可以解决:"基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系"

               System.Net.ServicePointManager.ServerCertificateValidationCallback =

               delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors)

               {

                   return true;

               };

                // 建立信任连接

                //exchangeServer.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

                //exchangeServer.Credentials = System.Net.CredentialCache.DefaultCredentials;

                //exchangeServer.UseDefaultCredentials = true;

                string url = string.Format("{0}/EWS/Exchange.asmx", connectionString);

                if (connectionString.IndexOf("|") > -1)

                {

                    string[] strs = connectionString.Split('|');

                    url = string.Format("{0}/EWS/Exchange.asmx", strs[0]);

                    System.Net.NetworkCredential nc = new System.Net.NetworkCredential(strs[1], strs[2], strs[3]);

                    string userEmail = SPContext.Current.Web.CurrentUser.Email;

                    if (userName.IndexOf("@") < 0) {

                        throw new Exception(SPContext.Current.Web.CurrentUser.Name+"用户未配置邮件地址.");

                    }

                    exchangeServer.Credentials = nc;

                    ExchangeImpersonationType exExchangeImpersonation = new ExchangeImpersonationType();

                    ConnectingSIDType csConnectingSid = new ConnectingSIDType();

                    csConnectingSid.Item = userEmail;

                    exExchangeImpersonation.ConnectingSID = csConnectingSid;

                    exchangeServer.ExchangeImpersonation = exExchangeImpersonation;

                }

                else

                {

                    exchangeServer.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

                }



                exchangeServer.Url = url;



                // 定义邮件的收件箱

                  DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];

                folderIDArray[0] = new DistinguishedFolderIdType();

                folderIDArray[0].Id = DistinguishedFolderIdNameType.inbox;



                FindItemType findItemRequest = new FindItemType();

                findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

                ItemResponseShapeType itemProperties = new ItemResponseShapeType();

                //

                itemProperties.BaseShape = DefaultShapeNamesType.IdOnly;

                findItemRequest.ItemShape = itemProperties;

                findItemRequest.ParentFolderIds = folderIDArray;

                RestrictionType restriction = new RestrictionType();

                IsEqualToType isEqualTo = new IsEqualToType();

                PathToUnindexedFieldType pathToFieldType = new PathToUnindexedFieldType();

                pathToFieldType.FieldURI = UnindexedFieldURIType.messageIsRead;

                FieldURIOrConstantType constantType = new FieldURIOrConstantType();

                ConstantValueType constantValueType = new ConstantValueType();

                constantValueType.Value = "0";

                constantType.Item = constantValueType;

                isEqualTo.Item = pathToFieldType;

                isEqualTo.FieldURIOrConstant = constantType;

                restriction.Item = isEqualTo;

                findItemRequest.Restriction = restriction;

                //SPSecurity.RunWithElevatedPrivileges(delegate()

                //{

                // 获取邮件

                FindItemResponseType firt = exchangeServer.FindItem(findItemRequest);



                FindItemResponseMessageType folder = (FindItemResponseMessageType)firt.ResponseMessages.Items[0];

                ArrayOfRealItemsType folderContents = new ArrayOfRealItemsType();

                folderContents = (ArrayOfRealItemsType)folder.RootFolder.Item;

                ItemType[] items = folderContents.Items;

                unreadCount = items == null ? 0 : items.Length;

                //});

                return unreadCount;

            }

            catch (Exception ex)

            {

                throw ex;            
         }



        }



    }

}
 
 
说明: 配置文件: <add key=”ExchangeContext” value=”https://mail.mailServer.com|administrator|p@ssw0rd|domain.com” />
目前我使用:exchangeServer.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials 一直抛出401 错误. 如果你成功了,不妨告诉我一下, 因为配置模拟账户和密码的确不是很好.
如果exchange服务器上面你没有配置过模拟账号,那么你将得到"该帐户无权模拟所请求的用户",这个问题困扰了很多天, 因为exchange上面的设置我不是很懂, 其实网上很多人也遇到该问题, 只是我关键字没有用对, 所以找问题关键字很重要. 如果你也遇到同样问题了,很庆幸, 这里给你答案: 
1.Open the Exchange Management Shell
2.输入: New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:administrator 
administrator就是你要设置的模拟账号,当然你也可以设置其他.
Configuring Exchange Impersonation:http://msdn.microsoft.com/en-us/library/bb204095.aspx
 
如果你需要读取未读邮件的标题和内容等其他内容,itemProperties.BaseShape = DefaultShapeNamesType.IdOnly; 需要修改为:itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;前者只读取了ID属性,如果你试图获取其他字段将得到一个异常.
 
code: 获取未读邮件带标题.
int unReadCount = items == null ? 0 : items.Length;



                System.Text.StringBuilder sb = new System.Text.StringBuilder();



                string linkUrl = @"<a href=""" + ConfigurationManager.AppSettings["MailServer"] + @""" title=""{0}"" target=""_blank"">{0}</a>";

                sb.Append(string.Format(linkUrl, "未读邮件:[" + unReadCount + "]封");

                sb.Append("<ul>");

                int titleLength = 0;

                int.TryParse(HttpContext.Current.Request.QueryString["tl"], out titleLength);

                if (items != null)

                {

                    foreach (ItemType curItem in items)

                    {

                        string subject = (curItem.Subject ?? "").Trim();

                        sb.Append("<li>" + string.Format(linkUrl, subject, (subject.Length > titleLength ? subject.Substring(0, titleLength) + "..." : subject)) + "</li>");

                    }

                }

                sb.Append("</ul>");

                return sb.ToString();
 
 
另:如果邮件已经从服务器中获取了, 那么获取outlook中未读邮件可用下面方法: 
using Outlook = Microsoft.Office.Interop.Outlook;
public int GetUnreadMailCount()



        {



            Outlook.Application outlook = new Outlook.ApplicationClass();



            Outlook.NameSpace ns = outlook.GetNamespace("MAPI");



            object _missing = Type.Missing;



            ns.Logon(_missing, _missing, false, true);



            Outlook.MAPIFolder inbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);



            int unread = inbox.UnReadItemCount;



            return unread;



        }
 
区别在于:一个在服务器中获取未读邮件(确切的应该叫未收邮件),一个在客户端获取未读邮件.
 

http://msdn.microsoft.com/en-us/library/bb204095.aspx

http://support.microsoft.com/kb/2015567

http://blogs.msdn.com/b/webdav_101/archive/2008/10/02/links-on-common-exchange-web-services-ews-questions.aspx

 

由于当时网上参考比较多,不能一一罗列链接.

你可能感兴趣的:(Exchange)