【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
由于当时网上参考比较多,不能一一罗列链接.