在C#中使用Pop3阅读电子邮件


75

我正在寻找一种在C#2.0中使用Pop3阅读电子邮件的方法。目前,我正在使用在CodeProject代码。但是,此解决方案并不理想。最大的问题是它不支持以unicode编写的电子邮件。

Answers:



16

通过POP3协议下载电子邮件是任务的轻松部分。该协议非常简单,如果您不想通过网络发送明文密码(并且不能使用SSL加密的通信通道),那么唯一的难题就是高级身份验证方法。有关详细信息,请参阅RFC 1939:邮局协议-版本3 RFC 1734:POP3身份验证命令

当您必须解析收到的电子邮件时,困难的部分就来了,在大多数情况下,这意味着解析MIME格式。您可以在几小时或几天内编写快速且肮脏的MIME解析器,它将处理95%以上的所有传入邮件。改进解析器,使其几乎可以解析任何电子邮件意味着:

  • 获取从最受欢迎的邮件客户端发送的电子邮件样本并改进解析器,以修复由它们产生的错误和RFC错误解释。
  • 确保违反RFC的消息头和内容的消息不会使解析器崩溃,并且您将能够从错误的电子邮件中读取所有可读或可猜测的值
  • 正确处理国际化问题(例如,从右到左书写的语言,特定语言的正确编码等)
  • 统一码
  • “ Mime酷刑电子邮件样本”中看到的附件和分层消息项树
  • S / MIME(已签名和加密的电子邮件)。
  • 等等

调试功能强大的MIME解析器需要花费数月的时间。我知道,因为我正在看着我的朋友为下面提到的组件编写一个这样的解析器,并且也在为它编写一些单元测试;-)

回到原来的问题。

以下代码取自我们的POP3教程页面和链接,将为您提供帮助:

// 
// create client, connect and log in 
Pop3 client = new Pop3();
client.Connect("pop3.example.org");
client.Login("username", "password");

// get message list 
Pop3MessageCollection list = client.GetMessageList();

if (list.Count == 0)
{
    Console.WriteLine("There are no messages in the mailbox.");
}
else 
{
    // download the first message 
    MailMessage message = client.GetMailMessage(list[0].SequenceNumber);
    ...
}

client.Disconnect();

8
基本上,您说的是“购买我的组件”,对吧?没错,听起来像是一个很好的组件。
MarkJ

3
您可以尝试任何第三方组件(免费或商业)。我的帖子试图指出,编写此类组件既困难又耗时,因为需要进行广泛的测试-如果没有大量来自真实用户的数据的大量错误报告,您几乎无法做到这一点。如果您选择Rebex组件会很好,但是如果您选择另一个组件,我对此没有任何问题。在这种情况下,恕我直言,编写自己的MIME解析器或使用一些在Web上找到的概念验证代码不是最好的方法。但是,我可能会有偏见;-),得出您自己的结论并首先测试代码。
Martin Vobr,09年

我可以使用Rebex组件从Exchange 2003收件箱中获取邮件吗?
Kiquenet

4
作者对MIME解析有多困难的讨论受到了他对没有人尝试MIME的兴趣。
约翰·梅尔维尔

1
@ThunderGr:关于解码器的要点。我想这取决于什么更有效。如果更容易编写自己的解码器,那就去吧。如果您的主要任务是完成另一件事,然后解码某些内容,那只是我尝试使用现成的解决方案的一部分。归根结底,通常是要平衡是更容易驯服具有许多最佳实践的第三方库(并处理其他人的代码中的问题)还是从头开始编写(并处理以下事实)您可能不知道问题的全部范围)。
Martin Vobr 2013年


5

您还可以尝试Mail.dll邮件组件,它具有SSL支持,unicode和多国电子邮件支持:

using(Pop3 pop3 = new Pop3())
{
    pop3.Connect("mail.host.com");           // Connect to server and login
    pop3.Login("user", "password");

    foreach(string uid in pop3.GetAll())
    {
        IMail email = new MailBuilder()
            .CreateFromEml(pop3.GetMessageByUID(uid));
          Console.WriteLine( email.Subject );
    }
    pop3.Close(false);      
}

您可以在这里https://www.limilabs.com/mail下载

请注意,这是我创建的商业产品。


1
我可以使用它来访问收件箱Exchange 2003吗?
Kiquenet

是的你可以。您只需要启用IMAP或POP3协议。
Pawel Lesnikowski 2012年

4

称我为老派,但为什么要使用第3方库作为简单协议。我已经使用System.Net.Sockets.TCPClient和System.Net.Security.SslStream在基于Web的ASP.NET应用程序中实现了POP3阅读器,以进行加密和身份验证。就协议而言,一旦您打开与POP3服务器的通信,就只需要处理少数命令。这是一个非常容易使用的协议。


4

我不推荐OpenPOP。我只花了几个小时来调试问题-OpenPOP的POPClient.GetMessage()神秘地返回了null。我调试了它,发现它是一个字符串索引错误-请参阅我在此处提交的补丁:http : //sourceforge.net/tracker/ ? func=detail&aid=2833334&group_id=92166&atid=599778 。很难找到原因,因为有空的catch {}块吞下了异常。

此外,该项目大部分处于休眠状态,最新版本是2004年。

目前,我们仍在使用OpenPOP,但我将看看人们在这里推荐的其他一些项目。


有什么建议吗?thx
Kiquenet

16
你好 我取代了OpenPop.NET项目,并将其置于功能更强大的状态。这些尝试捕获已被删除,并且库现在更加稳定。我认为该帖子条目不再有效。
foens 2011年

4

HigLabo.Mail易于使用。这是一个示例用法:

using (Pop3Client cl = new Pop3Client()) 
{ 
    cl.UserName = "MyUserName"; 
    cl.Password = "MyPassword"; 
    cl.ServerName = "MyServer"; 
    cl.AuthenticateMode = Pop3AuthenticateMode.Pop; 
    cl.Ssl = false; 
    cl.Authenticate(); 
    ///Get first mail of my mailbox 
    Pop3Message mg = cl.GetMessage(1); 
    String MyText = mg.BodyText; 
    ///If the message have one attachment 
    Pop3Content ct = mg.Contents[0];         
    ///you can save it to local disk 
    ct.DecodeData("your file path"); 
} 

您可以从https://github.com/higty/higlabo或Nuget [HigLabo]获取它


2

我刚刚尝试了SMTPop,它起作用了。

  1. 我下载了这个
  2. 添加了smtpop.dll对我的C#.NET项目的引用

编写以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;    
using SmtPop;

namespace SMT_POP3 {

    class Program {
        static void Main(string[] args) {
            SmtPop.POP3Client pop = new SmtPop.POP3Client();
            pop.Open("<hostURL>", 110, "<username>", "<password>");

            // Get message list from POP server
            SmtPop.POPMessageId[] messages = pop.GetMailList();
            if (messages != null) {

                // Walk attachment list
                foreach(SmtPop.POPMessageId id in messages) {
                    SmtPop.POPReader reader= pop.GetMailReader(id);
                    SmtPop.MimeMessage msg = new SmtPop.MimeMessage();

                    // Read message
                    msg.Read(reader);
                    if (msg.AddressFrom != null) {
                        String from= msg.AddressFrom[0].Name;
                        Console.WriteLine("from: " + from);
                    }
                    if (msg.Subject != null) {
                        String subject = msg.Subject;
                        Console.WriteLine("subject: "+ subject);
                    }
                    if (msg.Body != null) {
                        String body = msg.Body;
                        Console.WriteLine("body: " + body);
                    }
                    if (msg.Attachments != null && false) {
                        // Do something with first attachment
                        SmtPop.MimeAttachment attach = msg.Attachments[0];

                        if (attach.Filename == "data") {
                           // Read data from attachment
                           Byte[] b = Convert.FromBase64String(attach.Body);
                           System.IO.MemoryStream mem = new System.IO.MemoryStream(b, false);

                           //BinaryFormatter f = new BinaryFormatter();
                           // DataClass data= (DataClass)f.Deserialize(mem); 
                           mem.Close();
                        }                     

                        // Delete message
                        // pop.Dele(id.Id);
                    }
               }
           }    
           pop.Quit();
        }
    }
}

我已经尝试了您的代码,但是没有电子邮件正文-除了正文之外,所有详细信息都正常出现?任何想法 ?????
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.