myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Gemeinschaft » .NET-Komponenten und C#-Snippets » E-Mails versenden
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

E-Mails versenden

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
C#ler C#ler ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2011
Beiträge: 48
Entwicklungsumgebung: Visual Studio 2010


C#ler ist offline

E-Mails versenden

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Beschreibung:

Mit diesem Code kann man E-Mails versenden.
(Man ersetze die Angaben in den </>-Klammern durch den Wert!)

C#-Code:
using System;
using System.Net;
using System.Net.Mail;
using System.Web;

...

public void sendmail()
{
            try
            {
                MailMessage mail = new MailMessage(new MailAddress(<Absender-E-Mail-Adresse>,<Absendername>), new MailAddress(<Empfänger-E-Mail-Adresse>, <Empfängername>));
                mail.Subject = <Betreff>;
                mail.Body = <Inhalt>;
                SmtpClient sc = new SmtpClient(<SMTP-Server-Adresse Absender>, <Port>);
                sc.UseDefaultCredentials = false;
                sc.Credentials = new NetworkCredential(<Absender-E-Mail-Adresse>, <Absender-Passwort>);
                sc.Send(mail);
                MessageBox.Show("E-Mail erfolgreich gesendet.");
            }
            catch (Exception)
            {
                MessageBox.Show("Fehler beim Senden der E-Mail.");
            }
}

Schlagwörter: E-Mail, EMail, Email, Senden, SMTP, NetworkCredential, System.Net, System.Web, MailMessage
02.04.2011 22:23 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
herbivore
myCSharp.de-Poweruser/ Experte

avatar-2627.gif


Dabei seit: 11.01.2005
Beiträge: 49.474
Entwicklungsumgebung: csc/nmake (nothing is faster)
Herkunft: Berlin


herbivore ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo C#ler,

danke für das Snippet. Ich denke, da steckt noch einiges an Verbesserungspotenzial drin. So wie es jetzt ist, müssten man den Code für verschiedene Empfänger immer kopieren und dann die Werte direkt im Code füllen. Besser wäre es die Werte per Parameter zu übergeben.

Leider hat man dann eine lange Liste von String-Parametern und kann beim Aufruf leicht verwechseln, ob nun zuerst den Empfänger kommt und dann der Absender oder andersherum. Wenn du sprechende Parameternamen verwendest, kann man aber als Aufrufer ab C# 4.0 wenigstens benannte Parameter verwenden. Bei der Gelegenheit könntest du dann bestimmte Parameter auch optional machen, z.B. den Port (oder sogar den Body, denn für manche Zwecke reicht es ja, nur den Betreff zu verwenden.

Um das Problem mit der langen Parameter-Liste (für C# < 4.0) zu beheben, könntest du eine Klasse EMail o.ä. schreiben, die für jeden Parameter eine passende Property besitzt. So kann der Aufrufer seine Werte in die Properties füllen und dann das fertige Objekt an deine Methode übergeben oder du machst die Methode gleich zur Instanzmethode der Klasse.

herbivore
03.04.2011 07:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
C#ler C#ler ist männlich
myCSharp.de-Mitglied

Dabei seit: 02.04.2011
Beiträge: 48
Entwicklungsumgebung: Visual Studio 2010

Themenstarter Thema begonnen von C#ler

C#ler ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Also, v2.0

C#-Code:
class Mail
{
public string sendAddress, sendName, receiveAddress, receiveName, subject, body, smtp, password;
public int port;
public Mail(string sendAddress, string sendName,string receiveAddress, string receiveName, string subject, string body, string smtp, string password, int port)
{
this.sendAddress = sendAddress;
this.sendName = sendName;
this.receiveAddress = receiveAddress;
this.receiveName = receiveName;
this.subject = subject;
this.body = body;
this.smpt = smtp;
this.password = password;
this.port = port;
}
public void sendmail(Mail m)
{
            try
            {
                MailMessage mail = new MailMessage(new MailAddress(m.sendAddress,m.sendName), new MailAddress(m.receiveAddress, m.receiveName));
                mail.Subject = m.subject;
                mail.Body = m.body;
                SmtpClient sc = new SmtpClient(m.smtp, m.port);
                sc.UseDefaultCredentials = false;
                sc.Credentials = new NetworkCredential(m.sendAddress, m.password);
                sc.Send(mail);
                MessageBox.Show("E-Mail erfolgreich gesendet.");
            }
            catch (Exception)
            {
                throw new MailException("Fehler beim Senden der E-Mail.");
            }
}
public MailException : Exception
{
public MailException(string message) : base(message) { }
}
}
03.04.2011 15:22 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
xxMUROxx xxMUROxx ist männlich
myCSharp.de-Mitglied

avatar-3236.jpg


Dabei seit: 11.01.2010
Beiträge: 1.552
Entwicklungsumgebung: VS 13, SSMS 12
Herkunft: Südtirol/Italien


xxMUROxx ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wobei immer noch das Problem besteht dass du alle Parameter angeben musst. Dies wäre bei folgendem nicht der Fall:

C#-Code:
public Mail(string sendAddress,string sendName = null, string receiveAddress)
{[...]}

dies könnte wie folgt aufgerufen werden.

C#-Code:
new Mail("aaa");
new Mail("aaa","bbb");
new Mail("aaa","bbb","ccc");
new Mail("aaa",receiveAddress:"ccc");

Wobei dann immer noch das ewig lange Konstructor schreiben ist.
Kürzer gings dann wie herbivore sagt mit Properties

C#-Code:
public class Mail
{
    public SendName{get;set;}
    public SendAddress{get;set;}
    public ReceiveAddress{get;set;
}

welches dann wie folgt aufgerufen werden kann.

C#-Code:
Mail m = new Mail();
m.SendName = "...";

Wie du es dann machst ist nicht so tragisch, schlimmer finde ich die sendmail Methode. Sie ist eine Methode in der Mail Klasse und nicht statisch. Wenn sie statisch wäre, wäre es eine andere Angelegenheit. Die sendmail methode wird immer auf einem Object des Typs Mail aufgerufen. Warum übergibst du dann ein Mail Object. Normalerweise sollte die sendmail Methode jene Mail versenden auf welche die Methode aufgerufen worden ist. Denn bei dir ist folgendes möglich:

C#-Code:
Mail m1 = new Mail();
Mail m2 = new Mail();
m1.sendmail(m2);
m2.sendmail(m2);

Wobei dann logischerweise beidesmal m2 versendet wird, aber nicht sollte.
Besser wäre es wenn du es wie folgt hättest:

C#-Code:
Mail m1 = new Mail();
Mail m2 = new Mail();
m1.sendmail();
m2.sendmail();

public class Mail
{
    public void sendmail(){...}
}

Dann wäre schlussendlich noch ein Vorschlag zu dem trow: Als Benutzer der Methode sieht man leider nur dass ein Fehler aufgetreten ist aber nicht welcher. Entweder sollte deine Exception-Klasse geändert werden dass der base Contructor 2.Überladung von Exception(string message,Exception innerException) aufgerufen werden (inner Exception wäre der Fehler der im try Block geworfen wird) oder du solltest die exception die in sendMail geworfen wird nicht abfangen und nach oben werfen.

Ich hoffe ich konnte es verständlich genug erklären.

Gruß
Michael

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von xxMUROxx am 03.04.2011 20:59.

03.04.2011 20:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
tom-essen tom-essen ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2140.png


Dabei seit: 15.05.2005
Beiträge: 1.815
Entwicklungsumgebung: VS.NET 2013
Herkunft: NRW


tom-essen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo!

Und dann gibt's noch das "Problem" mit den exceptions.
Du fängst einfach alle ab, und erstellst dafür eine neue. In der aufrufenden Methode besteht dann keine Möglichkeit mehr, den aufgetretenen Fehler zu spezifizieren. Zumindest sollte die ursprüngliche Exception mit übergeben werden (InnerException).

EDIT: Nach interner Diskussion mit herbivore angepasst

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von tom-essen am 06.04.2011 11:04.

04.04.2011 09:55 Beiträge des Benutzers | zu Buddylist hinzufügen
Stipo Stipo ist männlich
myCSharp.de-Mitglied

avatar-2966.gif


Dabei seit: 09.04.2007
Beiträge: 699
Entwicklungsumgebung: VS 2010 Pro, Blend 4
Herkunft: Lörrach


Stipo ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo C#ler,

ich sehe bei Dir einige Fehler, die ich anfangs auch gemacht habe. Abgesehen von den obigen Kommentaren, kommt noch folgendes hinzu:
  • MessageBox.Show() gehört in die GUI rein. Wenn Du in der Klasse ausgaben machen möchtest, dann kannst Du das über Events nach außen geben  [FAQ] Eigenen Event definieren / Information zu Events , so kann der Anwender der Klasse, dann selbst entscheiden, was er mit der Meldung machen will.
    Für dich als Developer, gehen auch Präprozessordirektiven in denen Du dann Debug Meldungen in das Visual Studio Ausgabefenster schreiben kannst.  #if (C#-Referenz), oder meistens auch ausreichend die  Debug-Methoden.
  • Du übernimmst die Werte im Konstruktor ungeprüft. Es macht wenig sinn, wenn man eine Mail versenden möchte, das man einen leeren SmtpUserName angeben kann. Dies sollte man dann sofort mit einer  ArgumentException dem aufrufer melden.
  • DIe SmtpClient Klasse nutzt Unmanaged Methoden. Diese muss man nach der verwendung mit Dispose wieder freigeben. Lese Dir da mal zu der  SmtpClient.Dispose() Methode und  using-Anweisung die MSDN durch. Da hast Du dir nämlich eines der guten Beispiele der MSDN ausgesucht, wo das Thema Dispose sehr gut erklärt wird.
Als anmerkung zu deiner Exception Klasse noch. Ich hab mir das so angewöhnt, wenn ich Exceptions nicht selbst und direkt behandeln kann in meiner Klasse, lasse ich die laufen und werfe die nur weiter nach oben. So muss sich dann der aufrufer um das Problem kümmern und kann wiederum selbst entscheiden, was er damit machen will.
Eigene Exception Klassen verwende ich nur, wenn innerhalb meiner Klasse neue Exception entstehen können, die ich dann nach oben melden möchte, sofern es in der MSDN dazu noch keine fertigen Exception schon gibt, die das Problem behandeln (siehe ArgumentException).

So das sollte Dir dann noch weiterhelfen, um die Klasse besser zu designen.

Grüße Stephan

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Stipo am 04.04.2011 21:59.

04.04.2011 21:57 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Zwischen diesen beiden Beiträgen liegt mehr als ein Monat.
Inso Inso ist männlich
myCSharp.de-Mitglied

Dabei seit: 04.06.2010
Beiträge: 19
Entwicklungsumgebung: Visual Studio 2010 Prof.


Inso ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top


Respekt, wie viel konstruktive Kritik auf das Thema folgt.
Bin auf die Änderungen gespannt.
Daumen hoch
25.05.2011 11:46 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 9 Jahre.
Der letzte Beitrag ist älter als 9 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 27.05.2020 07:19