在 C# 中从 Gmail 中读取电子邮件

Posted

技术标签:

【中文标题】在 C# 中从 Gmail 中读取电子邮件【英文标题】:Reading emails from Gmail in C# 【发布时间】:2011-10-26 18:27:34 【问题描述】:

我正在尝试阅读来自 Gmail 的电子邮件。我已经尝试了我能找到的每一个 API / 开源项目,但都无法让它们工作。

有没有人有一个工作代码示例,可以让我从 Gmail 帐户验证和下载电子邮件?

下面发布的最终工作版本:https://***.com/a/19570553/550198

【问题讨论】:

您可以通过 IMAP 访问 Gmail。看到这个问题:***.com/questions/670183/accessing-imap-in-c @Kiquenet 最终工作版本发布在下面:***.com/a/19570553/550198 那么标记为最终答案。 【参考方案1】:

你试过 POP3 Email Client with full MIME Support 吗?

如果你不这样做,这对你来说是一个很好的例子。作为替代方案;

OpenPop.NET

C# 中的.NET 类库,用于与 POP3 服务器进行通信。易于 使用但功能强大。包括一个强大的 MIME 解析器,由几个 一百个测试用例。如需更多信息,请访问我们的项目主页。

Lumisoft

【讨论】:

谢谢,不知何故我设法尝试了每一个 C# 非工作 POP3 电子邮件客户端 :) 谢谢【参考方案2】:

你也可以试试Mail.dll IMAP client。

支持所有Gmail IMAP protocol extensions:

线程 ID, 消息 ID, 标签, 本地化文件夹名称, Google 搜索语法 OAuth 身份验证。

请注意,Mail.dll 是我开发的商业产品。

【讨论】:

我没有预算来支付这个,因为有开源和免费的替代品可用。 任何免费版本,而不是高级版本?任何开源替代品?【参考方案3】:

不需要任何额外的第三方库。您可以在此处从 Gmail 提供的 API 中读取数据:https://mail.google.com/mail/feed/atom

XML格式的响应可以通过下面的代码来处理:

try 
   System.Net.WebClient objClient = new System.Net.WebClient();
   string response;
   string title;
   string summary;

   //Creating a new xml document
   XmlDocument doc = new XmlDocument();

   //Logging in Gmail server to get data
   objClient.Credentials = new System.Net.NetworkCredential("Email", "Password");
   //reading data and converting to string
   response = Encoding.UTF8.GetString(
              objClient.DownloadData(@"https://mail.google.com/mail/feed/atom"));

   response = response.Replace(
        @"<feed version=""0.3"" xmlns=""http://purl.org/atom/ns#"">", @"<feed>");

   //loading into an XML so we can get information easily
   doc.LoadXml(response);

   //nr of emails
   var nr = doc.SelectSingleNode(@"/feed/fullcount").InnerText;

   //Reading the title and the summary for every email
   foreach (XmlNode node in doc.SelectNodes(@"/feed/entry")) 
      title = node.SelectSingleNode("title").InnerText;
      summary = node.SelectSingleNode("summary").InnerText;
   
 catch (Exception exe) 
   MessageBox.Show("Check your network connection");

【讨论】:

这种方法的唯一问题是你无法通过 ATOM 路由获取消息正文的全文,这对许多人来说很重要。 还有另一种用XML获取ATOM路由的方法。您只需为 XML 表单创建一个命名空间,就可以轻松访问它!阅读相关内容,您就会明白,因为它与此没有区别! :) 那么请说明您将如何检索邮件正文。 喜欢你的答案 - 现在每件事都需要 NuGet 包才能实现吗?这就是我们变成的样子吗:( 我收到了 401 Unauthorized 错误。我应该如何解决这个问题?【参考方案4】:

使用库来自:https://github.com/pmengal/MailSystem.NET

这是我的完整代码示例:

电子邮件存储库

using System.Collections.Generic;
using System.Linq;
using ActiveUp.Net.Mail;

namespace GmailReadImapEmail

    public class MailRepository
    
        private Imap4Client client;

        public MailRepository(string mailServer, int port, bool ssl, string login, string password)
        
            if (ssl)
                Client.ConnectSsl(mailServer, port);
            else
                Client.Connect(mailServer, port);
            Client.Login(login, password);
        

        public IEnumerable<Message> GetAllMails(string mailBox)
        
            return GetMails(mailBox, "ALL").Cast<Message>();
        

        public IEnumerable<Message> GetUnreadMails(string mailBox)
        
            return GetMails(mailBox, "UNSEEN").Cast<Message>();
        

        protected Imap4Client Client
        
            get  return client ?? (client = new Imap4Client()); 
        

        private MessageCollection GetMails(string mailBox, string searchPhrase)
        
            Mailbox mails = Client.SelectMailbox(mailBox);
            MessageCollection messages = mails.SearchParse(searchPhrase);
            return messages;
        
    

用法

[TestMethod]
public void ReadImap()

    var mailRepository = new MailRepository(
                            "imap.gmail.com",
                            993,
                            true,
                            "yourEmailAddress@gmail.com",
                            "yourPassword"
                        );

    var emailList = mailRepository.GetAllMails("inbox");

    foreach (Message email in emailList)
    
        Console.WriteLine("<p>0: 1</p><p>2</p>", email.From, email.Subject, email.Bodyhtml.Text);
        if (email.Attachments.Count > 0)
        
            foreach (MimePart attachment in email.Attachments)
            
                Console.WriteLine("<p>Attachment: 0 1</p>", attachment.ContentName, attachment.ContentType.MimeType);
            
        
    


另一个例子,这次使用MailKit

public class MailRepository : IMailRepository

    private readonly string mailServer, login, password;
    private readonly int port;
    private readonly bool ssl;

    public MailRepository(string mailServer, int port, bool ssl, string login, string password)
    
        this.mailServer = mailServer;
        this.port = port;
        this.ssl = ssl;
        this.login = login;
        this.password = password;
    

    public IEnumerable<string> GetUnreadMails()
    
        var messages = new List<string>();

        using (var client = new ImapClient())
        
            client.Connect(mailServer, port, ssl);

            // Note: since we don't have an OAuth2 token, disable
            // the XOAUTH2 authentication mechanism.
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            client.Authenticate(login, password);

            // The Inbox folder is always available on all IMAP servers...
            var inbox = client.Inbox;
            inbox.Open(FolderAccess.ReadOnly);
            var results = inbox.Search(SearchOptions.All, SearchQuery.Not(SearchQuery.Seen));
            foreach (var uniqueId in results.UniqueIds)
            
                var message = inbox.GetMessage(uniqueId);

                messages.Add(message.HtmlBody);

                //Mark message as read
                //inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
            

            client.Disconnect(true);
        

        return messages;
    

    public IEnumerable<string> GetAllMails()
    
        var messages = new List<string>();

        using (var client = new ImapClient())
        
            client.Connect(mailServer, port, ssl);

            // Note: since we don't have an OAuth2 token, disable
            // the XOAUTH2 authentication mechanism.
            client.AuthenticationMechanisms.Remove("XOAUTH2");

            client.Authenticate(login, password);

            // The Inbox folder is always available on all IMAP servers...
            var inbox = client.Inbox;
            inbox.Open(FolderAccess.ReadOnly);
            var results = inbox.Search(SearchOptions.All, SearchQuery.NotSeen);
            foreach (var uniqueId in results.UniqueIds)
            
                var message = inbox.GetMessage(uniqueId);

                messages.Add(message.HtmlBody);

                //Mark message as read
                //inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
            

            client.Disconnect(true);
        

        return messages;
    

用法

[Test]
public void GetAllEmails()

    var mailRepository = new MailRepository("imap.gmail.com", 993, true, "YOUREMAILHERE@gmail.com", "YOURPASSWORDHERE");
    var allEmails = mailRepository.GetAllMails();

    foreach(var email in allEmails)
    
        Console.WriteLine(email);
    

    Assert.IsTrue(allEmails.ToList().Any());

【讨论】:

我已经使用上面的代码在 c# 中构建了控制台应用程序,一切都已修复,但 gmail 不允许登录。这是我的错误消息:- ** failed : * NO [WEBALERT accounts.google.com/signin/… 需要 Web 登录。 161116082452398 NO [ALERT] 请通过网络浏览器登录:support.google.com/mail/accounts/answer/78754(失败)** 为了使其工作,您需要使用您的 gmail 帐户启用“不太安全的应用程序”,如果这是您的选项。我这样做了,现在代码可以工作了。在这里阅读更多:google.com/settings/security/lesssecureapps 我已经复制粘贴了你的代码。抛出异常:ActiveUp.Net.Imap4.dll 中尝试通过 GetAllMails("inbox") 获取邮件时出现“System.IndexOutOfRangeException”; 什么是? IMail 存储库。 Mailkit 没有那个接口。 @Nulle 这是来自我的代码库。您可以为自己的用例删除该接口。

以上是关于在 C# 中从 Gmail 中读取电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

在C#中从Gmail阅读电子邮件

无法在 codeigniter 中从 gmail 发送电子邮件,SMTP 身份验证错误

使用 Gmail API 阅读其他用户的电子邮件

是否可以在 gmail.com 帐户中找到从 C# 以编程方式发送的电子邮件?

如何在 php 中从 localhost 发送电子邮件?

GMAIL API 在 C# 中发送带附件的电子邮件