当前位置: 首页 > 知识库问答 >
问题:

使用获取gmail电子邮件。会员管理系统

陆运乾
2023-03-14

我正在尝试创建一个小Web应用程序来充当Gmail的Web邮件客户端...

我使用了以下代码从我的收件箱中获取电子邮件:

   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封邮件的电子邮件来做这件事,而且要花很长时间来获取所有的邮件....

共有1个答案

邹俊友
2023-03-14

如果您只需要消息的正文,您可以使用以下方法来减少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服务器上,只获取尽可能少的数据量,以便向用户显示您想要显示的内容。

还应该注意的是,您实际上并不需要使用< code > cancelationtokensource ,除非您实际上计划能够取消操作。

例如,您的代码段可以替换为:

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());
}

由于您正在将自己的webmail前端编写到GMail,您可能会发现以下建议很有用:

当您查看GMail webmail用户交互界面或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.
}

一旦用户单击一条消息来阅读它,您就可以使用<code>消息。Body以确定您实际需要下载哪些身体部位,以便向用户显示(即,避免下载附件等)。

有关如何执行此操作的示例,请查看 MailKit GitHub 存储库中包含的 ImapClientDemo 示例:https://github.com/jstedfast/MailKit

 类似资料:
  • 我试图了解Gmail API的工作原理。我的目标是在用户的收件箱中检索所有电子邮件的列表,并将其下载到。 目前的工作流程如下: > 使用Google提供的框架用OAuth 2.0授权我的iOS应用,我已经完成了这一步,我的应用可以成功授权一个gmail帐户。 下载电子邮件: 从文档来看,这似乎是显示消息列表的API调用: 去找https://www.googleapis.com/gmail/v1/

  • 问题内容: 我在使用Gmail PHP API时遇到问题。 我想检索电子邮件的正文内容,但是我只能对具有附件的电子邮件检索它!我的问题是为什么? 到目前为止,这是我的代码: 检索我知道的内容的第二种方法是使用位于“ 标题” 部分中的代码段,但它只能检索50个左右的前字符,这不是很有用。 问题答案: 让我们做一个小实验。我已经给自己发了两条消息。一个带有附件,一个没有附件。 请求: 响应: 我只要求

  • IM工作在一个小部件,显示未读电子邮件计数的Gmail和其他电子邮件帐户设置在智能手机。我使用谷歌邮件API为Gmail和它的作品查找,但我没有得到如何与正常的电子邮件应用程序的工作。 我尝试使用帐户管理器获取登录凭据并自己检索信息,但它没有运行,因为我无法获取任何密码。只需验证令牌。我在谷歌上找不到任何关于如何使用普通电子邮件帐户的解决方案,这些帐户不是来自谷歌邮件。 更新:我试图获得密码与此功

  • 需要使用spring boot从gmail发送邮件 但我得到了一个错误,就像 此应用程序没有/error的显式映射,因此您将其视为回退。 出现意外错误(type=内部服务器错误,状态=500)。邮件服务器连接失败;嵌套异常是com.sun.mail.util.MailConnectExc0019:无法连接到主机,端口:smtp.gmail.com,587;超时5000;嵌套异常是:java.net

  • 我正在尝试使用gmail从Delphi发送电子邮件。我有Indy10.5.9.0和Delphi XE3。 我从中获得了示例代码:http://www.andrecelestino.com/delphi-xe-envio-de-e-mail-com-componentes-indy/ 我还尝试了其他示例代码,但结果相同。 我有libeay32.dll和ssleay32.dll从这里:http://w

  • 我正在使用C#使用SMTP和gmail服务器发送电子邮件。 下面是我用于发送电子邮件的代码。我遇到了一些错误,即。 SMTP服务器需要安全连接,或者客户端未通过身份验证。服务器响应为:需要5.5.1身份验证。 我做错了什么?我如何使用gmail发送电子邮件。