Lesen von E-Mails mit Pop3 in C # [geschlossen]

75

Ich suche nach einer Methode zum Lesen von E-Mails mit Pop3 in C # 2.0. Derzeit verwende ich Code aus CodeProject . Diese Lösung ist jedoch nicht ideal. Das größte Problem ist, dass E-Mails, die in Unicode geschrieben wurden, nicht unterstützt werden.

Eldila
quelle

Antworten:

16

Das Herunterladen der E-Mail über das POP3-Protokoll ist der einfache Teil der Aufgabe. Das Protokoll ist recht einfach und der einzige schwierige Teil könnten erweiterte Authentifizierungsmethoden sein, wenn Sie kein Klartextkennwort über das Netzwerk senden möchten (und den SSL-verschlüsselten Kommunikationskanal nicht verwenden können). Weitere Informationen finden Sie unter RFC 1939: Post Office Protocol - Version 3 und RFC 1734: POP3 AUTHentication-Befehl .

Der schwierige Teil kommt, wenn Sie die empfangene E-Mail analysieren müssen, was in den meisten Fällen das Parsen des MIME-Formats bedeutet. Sie können in wenigen Stunden oder Tagen einen schnellen und schmutzigen MIME-Parser schreiben, der 95 +% aller eingehenden Nachrichten verarbeitet. Den Parser so zu verbessern, dass er fast jede E-Mail analysieren kann, bedeutet:

  • Abrufen von E-Mail-Beispielen von den beliebtesten E-Mail-Clients und Verbessern des Parsers, um von ihnen generierte Fehler und RFC-Fehlinterpretationen zu beheben.
  • Stellen Sie sicher, dass Nachrichten, die gegen RFC für Nachrichtenkopfzeilen und -inhalte verstoßen, Ihren Parser nicht zum Absturz bringen und dass Sie jeden lesbaren oder erratenen Wert aus der verstümmelten E-Mail lesen können
  • korrekter Umgang mit Internationalisierungsproblemen (z. B. von rechts nach links geschriebene Sprachen, korrekte Codierung für eine bestimmte Sprache usw.)
  • UNICODE
  • Anhänge und hierarchischer Nachrichtenelementbaum, wie in "Beispiel für Mime-Folter-E-Mail" zu sehen.
  • S / MIME (signierte und verschlüsselte E-Mails).
  • und so weiter

Das Debuggen eines robusten MIME-Parsers erfordert monatelange Arbeit. Ich weiß, weil ich meinem Freund beim Schreiben eines solchen Parsers für die unten erwähnte Komponente zugesehen habe und auch ein paar Unit-Tests dafür geschrieben habe ;-)

Zurück zur ursprünglichen Frage.

Der folgende Code aus unserer POP3-Tutorial-Seite und Links hilft Ihnen dabei:

// 
// 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();
Martin Vobr
quelle
8
Grundsätzlich sagst du "kaufe meine Komponente", oder? Daran ist nichts auszusetzen, es klingt nach einer guten Komponente.
MarkJ
3
Sie können jede Komponente von Drittanbietern (kostenlos oder kommerziell) ausprobieren. In meinem Beitrag wollte ich darauf hinweisen, dass das Schreiben einer solchen Komponente sowohl schwierig als auch zeitaufwändig ist, da umfangreiche Tests erforderlich sind - etwas, das Sie ohne zahlreiche Fehlerberichte mit Daten von einer großen Anzahl realer Benutzer kaum tun können. Es wäre schön, wenn Sie die Rebex-Komponente wählen würden, aber wenn Sie eine andere wählen, habe ich kein Problem damit. Das Schreiben eines eigenen MIME-Parsers oder die Verwendung eines Proof-of-Concept-Codes im Web ist meiner Meinung nach in diesem Fall nicht der beste Weg. Aber ich bin vielleicht voreingenommen ;-), ziehe deine eigene Schlussfolgerung und teste zuerst den Code.
Martin Vobr
Kann ich die Rebex-Komponente verwenden, um Nachrichten aus dem Exchange 2003-Posteingang abzurufen?
Kiquenet
4
Die Diskussion des Autors darüber, wie schwierig es ist, MIME zu analysieren, wird durch sein kommerzielles Interesse an niemandem beeinträchtigt, der es versucht.
John Melville
1
@ThunderGr: guter Punkt über Decoder. Ich denke, dass es davon abhängt, was effektiver ist. Wenn es einfacher ist, einen eigenen Decoder zu schreiben, machen Sie es. Wenn Ihre Hauptaufgabe darin besteht, eine andere Sache zu erledigen und etwas zu dekodieren, ist dies nur ein Teil davon, wenn ich versuchen würde, eine fertige Lösung zu verwenden. Letztendlich geht es normalerweise darum, abzuwägen, ob es einfacher ist, eine Drittanbieter-Bibliothek mit vielen eingebauten Best Practices zu zähmen (und Probleme im Code eines anderen zu beheben) oder sie von Grund auf neu zu schreiben (und damit umzugehen) Sie kennen wahrscheinlich nicht das volle Ausmaß des Problems.
Martin Vobr
8

Meine Open Source-Anwendung BugTracker.NET enthält einen POP3-Client, der MIME analysieren kann. Sowohl der POP3-Code als auch der MIME-Code stammen von anderen Autoren, aber Sie können sehen, wie alles in meiner App zusammenpasst.

Für die MIME-Analyse verwende ich http://anmar.eu.org/projects/sharpmimetools/ .

Siehe die Dateien POP3Main.cs, POP3Client.cs und insert_bug.aspx

Corey Trager
quelle
5

Sie können auch die Mail.dll-Mail-Komponente ausprobieren , die SSL-, Unicode- und multinationale E-Mail-Unterstützung bietet:

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

Sie können es hier unter https://www.limilabs.com/mail herunterladen

Bitte beachten Sie, dass dies ein kommerzielles Produkt ist, das ich erstellt habe.

Pawel Lesnikowski
quelle
1
Kann ich es für den Zugriff auf den Posteingang Exchange 2003 verwenden?
Kiquenet
Ja, du kannst. Sie müssen nur die IMAP- oder POP3-Protokolle aktivieren.
Pawel Lesnikowski
4

Nennen Sie mich altmodisch, aber warum sollten Sie eine Bibliothek eines Drittanbieters für ein einfaches Protokoll verwenden? Ich habe POP3-Reader in einer webbasierten ASP.NET-Anwendung mit System.Net.Sockets.TCPClient und System.Net.Security.SslStream für die Verschlüsselung und Authentifizierung implementiert. Was die Protokolle betrifft, müssen Sie nach dem Öffnen der Kommunikation mit dem POP3-Server nur noch eine Handvoll Befehle ausführen. Es ist ein sehr einfaches Protokoll, mit dem man arbeiten kann.

stephenbayer
quelle
4

Ich würde OpenPOP nicht empfehlen. Ich habe nur ein paar Stunden damit verbracht, ein Problem zu debuggen - OpenPOPs POPClient.GetMessage () gab auf mysteriöse Weise null zurück. Ich habe dies debuggt und festgestellt, dass es sich um einen String-Index-Fehler handelt - siehe den Patch, den ich hier eingereicht habe: http://sourceforge.net/tracker/?func=detail&aid=2833334&group_id=92166&atid=599778 . Es war schwierig, die Ursache zu finden, da es leere catch {} -Blöcke gibt, die Ausnahmen verschlucken.

Außerdem ist das Projekt größtenteils inaktiv ... die letzte Veröffentlichung war im Jahr 2004.

Im Moment verwenden wir noch OpenPOP, aber ich werde mir einige der anderen Projekte ansehen, die hier empfohlen wurden.

Richard Beier
quelle
Was empfiehlt dir? thx
Kiquenet
16
Hallo. Ich habe das OpenPop.NET-Projekt überholt und in einen funktionsfähigeren Zustand versetzt. Diese Versuchsfänge wurden entfernt und die Bibliothek ist jetzt viel stabiler. Ich glaube nicht, dass dieser Beitragseintrag mehr gültig ist.
Fohlen
4

HigLabo.Mail ist einfach zu bedienen. Hier ist ein Beispiel für die Verwendung:

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

Sie können es von https://github.com/higty/higlabo oder Nuget [HigLabo] erhalten

Higty
quelle
2

Ich habe gerade SMTPop ausprobiert und es hat funktioniert.

  1. Ich heruntergeladen dies .
  2. smtpop.dllVerweis auf mein C # .NET-Projekt hinzugefügt

Schrieb den folgenden Code:

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();
        }
    }
}
Ragunath Jawahar
quelle
Ich habe Ihren Code ausprobiert, aber es gibt keinen E-Mail-Text - alle Details außer Text kommen normalerweise ??? irgendeine Idee ?????
Abu Qauod