- 因为业务需求我需要将邮箱中的邮件保存到本地数据库进行分析,每次从服务器获取邮件的时候需要设置一个起始时间,这个起始时间就是本地数据库中上次获取的邮件中Date的最大值(邮件头中的Date)。
- 那么问题很简单,查询的时候使用sentsince 或者deliveredafter即可:
query = HeaderSearchQuery.SentSince(date);
- 然而,事情并没有那么简单。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/519e5852a80c28317f9c10e1bedc2a44.png)
- 你会发现,总会获取到设置的起始时间之前的邮件。这里要说一下,这个邮件,尤其是从国外发来的邮件,有一个时差问题,所以邮件头中的date要转换为localdatetime保存,不然混用会把人搞晕的。可以看到qq网易这些邮箱他们在界面上显示的都是localdatetime。
Envelope evlp = emhead.Envelope;
eMail.Date = evlp.Date != null ?
evlp.Date.Value.LocalDateTime : emhead.Date.LocalDateTime;
- 经过测试,当使用sentsince和deliveredafter是,实际上查询用的datetime是没有time的,只有date,所以起始时间都是从零点开始的,这就导致我们本来是要获取的是“2020/1/1 12:24:36”以后的邮件,但实际得到的是“2020/1/1 0:0:0”以后的邮件,这个有点坑,开发者在文档中也没有提到。
- 所以我只好在保存数据库时进行一个查询判断uniqueid是否已经存在了来解决这个问题。
select isnull((select top(1) 1 from mx_emails where UniqueId = xxxxxx), 0)
- 此外,由于服务器里面的邮件都是加密过的,所以searchquery中的大部分查询条件都是没法用的,比如subjectContains,fromContains等等。可以先通过访问使用fetch获取邮件的摘要信息(imap可以,pop3没有这个功能),然后再进行筛选。
var uids = folder.Search(query);
var emSummarys = folder.Fetch(uids, MessageSummaryItems.UniqueId
| MessageSummaryItems.Full | MessageSummaryItems.BodyStructure);