使用 .NET MVC 获取 gmail 电子邮件
Posted
技术标签:
【中文标题】使用 .NET MVC 获取 gmail 电子邮件【英文标题】:Fetching gmail emails using .NET MVC 【发布时间】:2016-06-25 14:22:07 【问题描述】:我正在尝试创建一个小的网络应用程序来充当 Gmail 的网络邮件客户端...
我使用以下代码从我的收件箱中获取电子邮件:
public ActionResult Index()
using (var client = new ImapClient())
using (var cancel = new CancellationTokenSource())
ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;
client.Connect("imap.gmail.com", 993, true, cancel.Token);
// If you want to disable an authentication mechanism,
// you can do so by removing the mechanism like this:
client.AuthenticationMechanisms.Remove("XOAUTH");
client.Authenticate("********@gmail.com", "****", cancel.Token);
// The Inbox folder is always available...
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly, cancel.Token);
m = new List<string>();
// download each message based on the message index
for (int i = 0; i < inbox.length; i++)
var message = inbox.GetMessage(i, cancel.Token);
m.Insert(i, message.TextBody);
client.Disconnect(true, cancel.Token);
return View(m.ToList());
我不喜欢这种做法的原因是这部分代码:
for (int i = 0; i < inbox.length; i++)
var message = inbox.GetMessage(i, cancel.Token);
m.Insert(i, message.TextBody);
提取所有邮件需要很长时间,大约每 5 秒提取 40 封邮件……所以如果有人有 2000 封邮件,加载所有邮件需要 20 分钟……
有没有更快的方法将所有电子邮件加载到我的 MVC 应用程序中? :/
附:我试过用有 10000 封电子邮件的电子邮件来做这件事,而且它需要很长时间才能获取所有电子邮件....
【问题讨论】:
这是什么 IMAP 库?它是否提供了一次获取多条消息的命令? 回应 Max 的问题,您使用的是什么 IMAP 库?您是否考虑过仅检索电子邮件标头?这会快得多,因为您没有检索身体和附件。如果用户想要打开特定的电子邮件,您可以这样做 这看起来像我的 IMAP 库 MailKit。 【参考方案1】:如果您只需要邮件的正文,则可以使用以下方法减少 IMAP 流量:
var messages = inbox.Fetch (0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);
int i = 0;
foreach (var message in messages)
var part = message.TextBody;
if (part != null)
var body = (TextPart) inbox.GetBodyPart (message.UniqueId, part);
m.Insert (i, body.Text);
else
m.Insert (i, null);
i++;
它的作用是向 IMAP 服务器发送批量 FETCH 请求,请求消息的“大纲”(也称为正文结构)及其唯一标识符。
紧随其后的循环会查看消息的结构,以找到包含消息正文的 MIME 部分,然后仅获取消息的特定子部分。
通常,您不会通过 IMAP 下载每条消息。 IMAP 的目的是将所有消息留在 IMAP 服务器上,并且只获取您需要的尽可能少的数据,以便向用户显示您想要显示的任何内容。
还应注意,您实际上不需要使用CancellationTokenSource
,除非您确实计划能够取消操作。
例如,您的代码 sn-p 可以替换为:
public ActionResult Index()
using (var client = new ImapClient())
ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;
client.Connect("imap.gmail.com", 993, true);
// If you want to disable an authentication mechanism,
// you can do so by removing the mechanism like this:
client.AuthenticationMechanisms.Remove("XOAUTH");
client.Authenticate("********@gmail.com", "****");
// The Inbox folder is always available...
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
m = new List<string>();
var messages = inbox.Fetch (0, -1, MessageSummaryItems.UniqueId | MessageSummaryItems.BodyStructure);
int i = 0;
foreach (var message in messages)
var part = message.TextBody;
if (part != null)
var body = (TextPart) inbox.GetBodyPart (message.UniqueId, part);
m.Insert (i, body.Text);
else
m.Insert (i, null);
i++;
client.Disconnect(true);
return View(m.ToList());
由于您正在为 GMail 编写自己的网络邮件前端,您可能会发现以下建议很有用:
当您查看 GMail 网络邮件用户界面或 Yahoo Mail! 的用户界面时,您可能已经注意到它们只向您显示最近的 50 条左右的邮件,您必须专门单击一个链接才能显示下一条一组 50 条消息等等,对吧?
这样做的原因是查询完整的消息列表并将它们全部下载(甚至只是所有消息的文本正文)效率低下。
他们所做的只是一次只要求 50 条消息。事实上,他们根本不要求消息,他们要求的摘要信息如下:
var all = inbox.Search (SearchQuery.All);
var uids = new UniqueIdSet ();
// grab the last 50 unique identifiers
int min = Math.Max (all.Count - 50, 0);
for (int i = all.Count - 1; i >= min; i--)
uids.Add (all[i]);
// get the summary info needed to display a message-list UI
var messages = inbox.Fetch (uids, MessageSummaryItems.UniqueId |
MessageSummaryItems.All | MessageSummaryItems.BodyStructure);
foreach (var message in messages)
// the 'message' will contain a whole bunch of useful info
// to use for displaying a message list such as subject, date,
// the flags (read/unread/etc), the unique id, and the
// body structure that you can use to minimize your query when
// the user actually clicks on a message and wants to read it.
一旦用户点击消息阅读它,那么您可以使用message.Body
找出您实际上需要下载哪些正文部分以便将其显示给用户(即避免下载附件等)。
有关如何执行此操作的示例,请查看 MailKit GitHub 存储库中包含的 ImapClientDemo 示例:https://github.com/jstedfast/MailKit
【讨论】:
以上是关于使用 .NET MVC 获取 gmail 电子邮件的主要内容,如果未能解决你的问题,请参考以下文章