C# Exchange ews 自用收发邮件工具类
网上找了好久的代码,结合微软的文档和网上代码总结下来这个工具类(对邮件的附件的操作暂时没有写,以后用到了再补上)
前置条件: 工具 -> NuGet包管理器 -> 管理解决方案的NuGet包管理器,选浏览,然后搜索 Microsoft.Exchange.WebServices.Data
期间我报错过一次 The Autodiscover service couldn't be located ,通过下面代码的注释方法都没有解决,后来下了源码进行修改以后才解决的,我的情况是服务器不在域中,但是dll内部会通过域的联系人啥啥啥的找到邮件服务器的AutodiscoverUrl,不过上面也说了,服务器不在域中,程序查不到就报错了,我的处理方法是修改源码,强行赋予它我们的url,然后就解决了。
最后附一下源码地址:GitHub - OfficeDev/ews-managed-api
using Microsoft.Exchange.WebServices.Data; using System; using System.Collections.Generic; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class EmailUtil_Exchange { /// <summary> /// 回调函数 /// </summary> /// <param name="args"></param> public delegate void CallBack(params object[] args); private ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013); public EmailUtil_Exchange(string email_user, string email_pwd) { service.Credentials = new WebCredentials(email_user, email_pwd); service.UseDefaultCredentials = true; service.TraceEnabled = false; service.AutodiscoverUrl(email_user, RedirectionUrlValidationCallback); } /// <summary> /// 如果上面的构造方法报The Autodiscover service couldn't be located这个错就用这个构造方法,原因大概是登录账户验证不过导致的 /// </summary> /// <param name="email_user"></param> /// <param name="user"></param> /// <param name="pwd"></param> /// <param name="exchangeAddress"></param> public EmailUtil_Exchange(string email_user, string domain, string user, string pwd, string exchangeAddress) { //至关重要的一句 否则会报错:The Autodiscover service couldn't be located. //ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; ServicePointManager.ServerCertificateValidationCallback = delegate ( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { // Trust all certificates. WARNING: Don't do this in production code! return true; }; service.Credentials = new NetworkCredential(user, pwd, domain); service.Url = new Uri($@"https://{exchangeAddress}/EWS/Exchange.asmx");//exchange服务器上接口地址 service.TraceEnabled = false;//这个是调试信息,建议在出问题的时候打开这个选项 service.AutodiscoverUrl(email_user); } /// <summary> /// 这个是和证书验证有关的东西,不用管,固定这么写 /// </summary> /// <param name="redirectionUrl"></param> /// <returns></returns> private bool RedirectionUrlValidationCallback(string redirectionUrl) { bool result = false; Uri redirectionUri = new Uri(redirectionUrl); if (redirectionUri.Scheme == "https") { result = true; } return result; } /// <summary> /// 发送邮件 /// </summary> /// <param name="subjetc">主旨</param> /// <param name="body">内容</param> /// <param name="toAddress">邮箱地址";"隔开 必填</param> /// <param name="ccAddress">邮箱地址";"隔开 没有就写空</param> public void SendMail(string subjetc, string body, string toAddress, string ccAddress) { EmailMessage email = new EmailMessage(service); string[] tempStr = toAddress.Split(';'); for (int i = 0; i < tempStr.Length; i++) { if (string.IsNullOrEmpty(tempStr[i])) { continue; } email.ToRecipients.Add(tempStr[i]); } //副本没写就不做处理 if (!string.IsNullOrEmpty(ccAddress)) { tempStr = ccAddress.Split(';'); for (int i = 0; i < tempStr.Length; i++) { if (string.IsNullOrEmpty(tempStr[i])) { continue; } email.CcRecipients.Add(tempStr[i]); } } email.Subject = subjetc; email.Body = new MessageBody(body); email.Send(); } /// <summary> /// 根据文件夹名获取文件id /// </summary> /// <param name="folderName"></param> /// <param name="wellKnownFolderName"></param> /// <param name="exchangeService"></param> /// <returns></returns> private FolderId GetFolderIdByFolderName(string folderName, WellKnownFolderName wellKnownFolderName) { FolderView folderView = new FolderView(10); FindFoldersResults folders = service.FindFolders(wellKnownFolderName, folderView); for (int i = 0; i < folders.Folders.Count; i++) { if (folders.Folders[i].DisplayName == folderName) { return folders.Folders[i].Id; } } return null; } /// <summary> /// 过滤器(有需求还可以再加) /// </summary> /// <returns></returns> private SearchFilter SetFilter(DateTime startTime, DateTime endTime, string subject) { List<SearchFilter> searchFilterCollection = new List<SearchFilter>(); SearchFilter start = new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeCreated, startTime); SearchFilter end = new SearchFilter.IsLessThanOrEqualTo(ItemSchema.DateTimeCreated, endTime); SearchFilter name = new SearchFilter.IsEqualTo(ItemSchema.Subject, subject); searchFilterCollection.Add(start); searchFilterCollection.Add(end); if (!string.IsNullOrEmpty(subject)) { searchFilterCollection.Add(name); } SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, searchFilterCollection.ToArray()); return filter; } /// <summary> /// 寻找邮件 /// </summary> /// <param name="startDate">邮件开始时间(这个时间开始的)</param> /// <param name="endDate">邮件结束时间(这个时间结束的)</param> /// <param name="folderName">邮箱下的文件夹名字(如果直接拿收件匣下的邮件就填空)</param> /// <param name="subject">等于这个标题的</param> /// <param name="callBack">回调</param> /// <param name="args">回调参数</param> public void FindMail(DateTime startDate, DateTime endDate, string folderName, string subject, CallBack callBack, params object[] args) { //建立筛选器 SearchFilter searchFilter = SetFilter(startDate, endDate, subject); ItemView itemView = new ItemView(30); FindItemsResults<Item> items; //寻找符合对象的条件的邮件 if (!string.IsNullOrEmpty(folderName)) { //通过邮件中的文件夹名字获取文件夹id FolderId folderId = GetFolderIdByFolderName(folderName, WellKnownFolderName.Inbox); if (folderId == null) { return; } items = service.FindItems(folderId, searchFilter, itemView); } else { items = service.FindItems(WellKnownFolderName.Inbox, searchFilter, itemView); } for (int i = 0; i < items.TotalCount; i++) { items.Items[i].Load(PropertySet.FirstClassProperties); string content = items.Items[i].Body.Text;//邮件内容 //items.Items[i].Delete(DeleteMode.HardDelete/*这是删除邮件,有三个选项,具体看dll的注释*/); if (callBack != null) { callBack(items.Items[i], content, args); } } } }