Montag, 6. September 2010

Emails senden

Hinweis: Dieser Post erklärt die Grundlagen des Sendens von Emails. Zur Zeit des Posts war dies noch ohne SSL möglich, heutzutage ist dies jedoch meist Voraussetzung. Daher erkläre ich das Senden von Emails unter Benutzung einer SSL-Verbindung in diesem neuen Post.

Erstaunlicherweise können Emails über C# mit nur wenigen Anweisungen versandt werden.
Die Klasse System.Net.Mail stellt die hierfür nötigen Funktionen bereit und muss daher im Projekt mittels using eingebunden werden.
Eine neue Email kann dann als Instanz der Klasse MailMessage erstellt werden.
Die Absenderadresse wird über die Eigenschaft From eingestellt, welche ein Objekt vom Typ MailAddress aufnimmt. To, Body und Subject sind vom Typ String und bezeichnen die Empfängeradresse, den Nachrichtentext und den Betreff der Nachricht.
Zum Versenden der Email wird eine Instanz der Klasse SmtpClient benötigt.
Diese erwartet im Konstruktor die Adresse des zu nutzenden Postausgangsserver (muss vom Typ SMTP sein) sowie den zu nutzenden Port.
Manche Emailserver erwarten vor dem Senden von Emails eine Anmeldung am Server. Dazu muss dann eine Instanz der Klasse System.Net.NetworkCredential angelegt werden, im Konstruktor werden Benutzername und Passwort übergeben.
Die Instanz wird dann der Eigenschaft Credentials der MailMessage Klasse zugewiesen.
Folgendes Beispiel ist ein kleine Konsolenanwendung, die eine neue Email mit den anhand der Daten erstellt und diese sendet:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail; // hinzufügen

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MailMessage Email = new MailMessage();

            Console.WriteLine("Absender:");
            MailAddress Sender = new MailAddress(Console.ReadLine());
            Email.From = Sender; // Absender einstellen

            Console.WriteLine("Empfänger:");
            Email.To.Add(Console.ReadLine()); // Empfänger hinzufügen

            Console.WriteLine("Betreff:");
            Email.Subject = Console.ReadLine(); // Betreff hinzufügen

            Console.WriteLine("Nachrichtentext:");
            Email.Body = Console.ReadLine(); // Nachrichtentext hinzufügen

            Console.WriteLine("Postausgangsserver:");
            string ServerName = Console.ReadLine();
            Console.WriteLine("Port:");
            string Port = Console.ReadLine();

            SmtpClient MailClient = new SmtpClient(ServerName, int.Parse(Port)); // Postausgangsserver definieren

            Console.WriteLine("Anmeldung erforderlich?"); // "Ja" oder "Nein" als Eingabe möglich

            bool LoginNecessary = (Console.ReadLine() == "Ja");
            if (LoginNecessary)
            {
                Console.WriteLine("Benutzername:");
                string UserName = Console.ReadLine();
                Console.WriteLine("Passwort:");
                string Password = Console.ReadLine();
                System.Net.NetworkCredential Credentials = new System.Net.NetworkCredential(UserName, Password);

                MailClient.Credentials = Credentials; // Anmeldeinformationen setzen*/
            }

            MailClient.Send(Email); // Email senden

        }
    }
}

Diese Methode zum Versenden von Emails funktioniert mit allen Emailprovidern, die als Postausgangsserver einen SMTP Server haben.
Wichtig ist, dass als Absender die tatsächliche Emailadresse eingegeben wird und die Serverinformationen stimmen (diese sind die gleichen wie im Emailprogram, z.B. Outlook, unter Kontenoptionen eingestellt).
Für den kostenlosen Emailanbieter WEB ist die Adresse des Postausgangsserver beispielsweise "smtp.web.de" und der richtige Port 25.
Beim ebenfalls kostenlosen Anbieter GMX muss der Server auf "mail.gmx.net" festgelegt werden und der Port wiederrum auf 25.
Die meisten Anbieter benötigen zum Versenden von Emails Anmeldeinformationen, WEB und GMX beispielsweise gehören auch dazu, hier muss also die Eigenschaft Credentials definiert werden.

Kommentare:

  1. Guter Artikel, zwei Fragen hab ich aber trotzdem.
    1. Wie findet man die Adresse des Postausgangsservers heraus.
    2. "WEB und GMX beispielsweise gehören auch dazu, hier muss also die Eigenschaft Credentials nicht definiert werden."

    Irgendwie muss man ja trotzdem Benutzer und Passwort übergeben, oder?

    AntwortenLöschen
  2. Hey.
    1. Die Adresse des Postausgangsservers kann man schlecht herausfinden, sie müsste irgendwo auf der Homepage deines Anbieters stehen (bzw. einfach googlen) - um welchen Anbieter geht's?
    2. Nein, man braucht sich bei WEB und GMX überhaupt nicht anmelden, habe ich im Post nachträglich auch noch extra betont.
    Die Angabe der richtigen Absenderemailadresse reicht aus, auch wenn's komisch klingt.
    Grüße!

    AntwortenLöschen
  3. 1. Ich hab da an Hotmail gedacht.
    2. Dann kann man ja irgendeinen Absender angeben...? Wenn ich es bei GMX ohne Login versuche bekomme ich folgende Fehlermeldung:
    5.7.0 Need to authenticate via SMTP-AUTH-Login {mp032}

    AntwortenLöschen
  4. Hallo,

    1. eine Liste mit POP3- und SMTP-Servern verschiedener Anbieter findest du hier: http://www.patshaping.de/hilfen_ta/pop3_smtp.htm
    Für Hotmail lautet der Postausgangsserver also smtp.live.com, der entsprechende Port ist 587.
    Hierbei ist auch eine Authentifizierung nötig, als Benutzername muss die vollständige Hotmail - Emailadresse angegeben werden.

    2. Ja hat mich auch erst gewundert, aber es funktioniert bei mir mit WEB und GMX. Warum's bei dir nicht klappt kann ich dir so nicht sagen (richtige Email eingegeben?), probier's doch einfach dann mal mit Anmelden, kann ja auch nie schaden.

    AntwortenLöschen
  5. Ja, mit Anmelden geht es. Vielen Dank für den Link.

    AntwortenLöschen
  6. Hey,
    sorry, Fehler meinerseits.
    Die Anmeldung bei WEB und GMX ohne Anmeldeinformationen hat nur geklappt, da ich mich vorher über Windows Live Mail bei diesen Konten angemeldet habe und dadurch die Verbindung noch aktiv war.
    Auch bei diesen Anbietern müssen also Benutzername und Passwort zum Versenden von Emails angegeben werden.
    Post entsprechend angepasst.

    AntwortenLöschen
  7. Sehr gute Sache!!!

    Was mich noch interresieren würde:
    Mal angenommen ich möchte eine Console die mich voll automatisch in einem Chatroom anmaldet. Also automatisch Firefox öffnet, in die URL_Leiste den Link zur Seite eingibt, dann meinen Username und mein Passwort eingibt und auf Login klickt.
    Ist das überhaupt möglich??????
    wäre cool wenn!!
    Vllt is das ja ne Herrausforderung oder auch nich!! :D

    AntwortenLöschen
  8. Hallo,

    möglich ist ja eigentlich alles wenn man nur will :-P
    Dein Problem ist ja aber sehr speziell, deswegen glaube ich leider eher nicht dass ich mal so einen Post schreibe. Das Programm muss ja ganz genau auf den Chat Room etc. abgestimmt sein.
    Prinzipiell fallen mir aber 2 Wege ein, dein Problem zu lösen: Beim 1. (der elegantere) versuchst du, über das verwendete Protokoll mit Webdiensten Daten aus dem Chat zu lesen und hinein zu schreiben - hierfür bräuchtest du gar keinen Browser sondern hättest dann deinen eigenen Client.
    Beim 2. (dem leichteren) kannst du versuchen, die beschriebenen Schritte (Firefox öffnen, einloggen usw.) zu simulieren, denn in C# gibt es ja Möglichkeiten, Tastendrücke oder Mausklicks zu simulieren (siehe z.B. SendKeys).
    Du kannst ja mal mit dem Programm anfangen und mich dann weiterfragen.
    Viele Grüße
    Oliver

    AntwortenLöschen
  9. Der Vorschlag mit SendKeys wäre dann doch etwa zu übertrieben finde ich. Aber Buttons auf Websiten zu klicken geht auch anders, du brauchst dazu nur die Id des Buttons.
    Dann erstellst du ein Objekt der Klasse HtmlDocument und über deren Eigenschaften kannst du dann mit Hilfe der Id auf diesen Button zugreifen und die Methode .Invoke("click") aufrufen.

    AntwortenLöschen
  10. Coole Sache, vielleicht schreibe ich demnächst mal was drüber.

    AntwortenLöschen
  11. Hallo, habe ein Problem: Jedes mal, wenn ich versuche, die E-Mail zu schicken, bekomme ich die Exception: "Smtp Exception wurde nicht behantdelt. / Fehler beim Senden von Mail."
    Habe es als Absender via Hotmail- und GMX-Adresse versucht.

    Danke im Voraus,
    Gruß,
    Ron

    AntwortenLöschen
  12. Diesen Fehler habe ich zwar nicht, aber ich schätze,dass du vertippt hast.

    Meine Frage:
    Kann man ein Betriebssystem in C# schreiben(Mir ist klar, dass das lange dauert), oder ist es an Windows Klassen gebunden?

    AntwortenLöschen
  13. Hallo, hat sich erledigt!

    Danke!

    AntwortenLöschen
  14. Hallo,

    wenn ihr alle ohne Namen postet komme ich leider nicht mehr mit, was sich erledigt hat - die Sache mit dem Sendefehler oder mit dem Betriebssystem? Ich gehe mal vom ersteren raus, war ein Vertipper drin?
    Und zum 2.: Ja, es gibt auch Betriebssystem, die mit C# geschrieben sind!
    Einfach mal googlen ;-)
    Zum einen wäre hier Cosmos (eher eine Art Toolbox zum selber schreiben), SharpOS und (teilweise) auch eins namens Singularity.

    Viele Grüße
    Oliver

    AntwortenLöschen
  15. Hallo,

    erstmal danke. Die Methode ist echt gut geschrieben und übersichtlich angeordnet.
    Jedoch habe ich ein kleines Problem. Als Empfänger verwende ich xxx@web.de. Daraus folgt, das der Server smtp.web.de heißt. Alles eingetragen usw. mit Anmeldung aber wenn ich nun Port 25 verwenden wie oben beschreiben wird mir der Fehler ausgegeben, dass die E-Mail ungueltig sei, was aber nciht sein kann, da ich alles mehrfach geprüft habe. Bei Abänderung des Ports auf 465 z.B. erscheint der Fehler, dass ein Fehler beim senden der Mail aufgetreten ist.

    Kannst du evt. helfen?

    AntwortenLöschen
  16. Hallo Dome,

    leider sagt mir dein Fehler jetzt nichts, bei mir funktioniert web.de.
    Hast du es mal mit einer neuen Adresse versucht oder mit anderen Anbietern?
    Klappt das?

    Viele Grüße
    Oliver

    AntwortenLöschen
  17. Hallo Oliver,
    danke für deinen Post, ist wirklich sehr hilfreich. Hab genau das gesucht...aber aus irgend einem Grund funktioniert mein Programm nicht.
    Hier ist der Code:
    /*

    private void button1_Click(object sender, EventArgs e)
    {
    string serverName = string.Empty;
    int port;
    MailMessage Email = new MailMessage();
    MailAddress Sender = new MailAddress(textEMail.Text + "@" + comboBox1.Text);
    Email.From = Sender;//Absender einstellen
    Email.To.Add("lavisingh@live.de");//Empfänger
    Email.Subject = Betreff.Text;
    Email.Body = textBody.Text;
    if (comboBox1.Text == "yahoo.com" || comboBox1.Text == "yahoo.de" || comboBox1.Text == "yahoo.it")
    {
    serverName = "smtp.mail.yahoo.com";
    port = 995;
    SmtpClient MailClient = new SmtpClient(serverName, port);
    MailClient.Send(Email);
    }

    }
    */

    hoffe, du findest den Fehler :)
    danke im Voraus
    LG
    Jonny

    AntwortenLöschen
  18. Hey Jonny,

    sorry für die späte Antwort. Hat sich dein Fehler mitlerweile erledigt?
    Wenn nein, was kommt denn für ein Fehler?
    Weil einfach so kann ich erstmal nichts falsches erkennen.

    Viele Grüße
    Oliver

    AntwortenLöschen
  19. Hallo,

    ich weiß nicht ob ihr das Problem schon gelöst habt, aber wenn da steht:

    Smtp Exception wurde nicht behantdelt. / Fehler beim Senden von Mail.

    dann das Viren schutzprogramm oder ggf. Firewall(aber eher nicht) ausschalten!

    Gruß
    outsideuser
    PS: das hat zumindest bei mir geholfen

    AntwortenLöschen
  20. Hallo.

    Ich habe dein Mail-Programm mal versucht zu benutzen nachdem ich alles eingegeben habe únd die Mail gesendet werden sollte tauchte bei mit ein Fehler auf, wegen dem das Programm geschlossen wurde. Habe die Hotmaildaten (smtp.live.com und 587) korrekt eingegeben weist du vielleicht woran das liegen kann?

    AntwortenLöschen
  21. Wie gesagt, ohne genauen Fehlercode o.ä. kann man leider nicht viel sagen ... Debugge das Programm doch mal Schritt für Schritt und schau, wie weit du kommst.

    AntwortenLöschen
  22. hi also ich wollte ma fragen was ich da jetzt ersetzen muss. Also könntest du mir das vllt noma schreiben mit gmx und als e-mail z.b. anonymus@gmx.de? Wäre super bin nämlich nich son genie bei mir zeigt der immer fehler xD. Naja schonma thx

    AntwortenLöschen
  23. Hi, was denn ersetzen? Das Programm fragt dich ja der Reihe nach Absender, Empfänger, Postausgangsserver etc. Die richtigen Daten kannst du (gleicher Link wie oben) auf folgender Seite nachschauen: http://www.patshaping.de/hilfen_ta/pop3_smtp.htm
    Grüße
    Oliver

    AntwortenLöschen
  24. Hi,
    vielen dank für den Code, hat mir sehr geholfen die Klasse Mail selber zu durchsuchen!

    MfG

    AntwortenLöschen
  25. Genial, danke für Deine Mühe!!!

    AntwortenLöschen
  26. Vielen, vielen Dank!!!!

    Liebe Grüße.

    AntwortenLöschen
  27. Ich wollte auch mich bei dir bedanken :)
    Vielen Dank

    AntwortenLöschen
  28. Hallo oliver
    wie siehts mit anhängen aus? :)

    AntwortenLöschen
    Antworten
    1. Attachment MyAttachment = new Attachment(path);
      mail.Attachments.Add(MyAttachment);

      Löschen
  29. Hallo Oliver,
    auch mich würde es interessieren, wie es mit Anhängen ausschaut. Zum anderen würde mich interessieren, ob man das ganze in einer Win 8 Metro App nutzen kann?

    AntwortenLöschen
  30. Hi,
    sehr interessant aber bei starto mail funktioniert das nicht, da strato Authentifizierung fordert.

    Für den SMTP-Server ist eine sichere Verbindung erforderlich, oder der Client wurde nicht authentifiziert. Die Serverantwort war: 5.7.0 User not authenticated

    AntwortenLöschen
  31. Hallo,
    ich hab immer bei der Zeile MailClient.Send(Email); den Fehler:
    Fehler beim Senden von Mail. System.IO.IOException: Von der Übertragungsverbindung können keine Daten gelesen werden: net_io_connectionclosed

    AntwortenLöschen
  32. Hi Oliver

    Merci für dein Post.

    Irgendwie bringe ich das aber nicht ganz hin: gmx.de verlangt eine https Anfrage (verschlüsselt, nicht http) und nun frage ich mich, wie ich das hinbekomme.

    Merci für eine baldige Antwort

    Fritz

    AntwortenLöschen
  33. Hallo,
    leider funtioniert das mit win8 und win10 nicht mehr, jemand ne Ahnung warum?

    AntwortenLöschen
  34. Hallo,
    es hat etwas gedauert, aber hier doch die Antwort - vielen Dank an alle die diesem Blog treu bleiben!
    Dieser Post wurde zu Zeiten geschrieben wo die Kommunikation ohne SSL möglich war, heutzutage geht das in der Regel nicht mehr. Im Prinzip muss man dafür nur den Stream austauschen und einen SslStream benutzen. Mit diesen neuen Informationen habe ich Post veröffentlich, dort kann das ganze als Code gesehen werden: http://csharp-tricks.blogspot.de/2016/10/emails-senden-und-empfangen-pop3-und.html

    AntwortenLöschen