it-swarm.com.de

Wie kann ich E-Mails über SSL SMTP mit .NET Framework senden?

Gibt es mit .NET Framework eine Möglichkeit, E-Mails über einen SSL-SMTP-Server an Port 465 zu senden?

Der übliche Weg:

System.Net.Mail.SmtpClient _SmtpServer = new System.Net.Mail.SmtpClient("tempurl.org");
_SmtpServer.Port = 465;
_SmtpServer.EnableSsl = true;
_SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password");
_SmtpServer.Timeout = 5000;
_SmtpServer.UseDefaultCredentials = false;

MailMessage mail = new MailMessage();
mail.From = new MailAddress(from);
mail.To.Add(to);
mail.CC.Add(cc);
mail.Subject = subject;
mail.Body = content;
mail.IsBodyHtml = useHtml;
_SmtpServer.Send(mail);

die Zeit ist abgelaufen:

System.Net Verbose: 0 : [1024] SmtpClient::.ctor(Host=ssl0.ovh.net, port=465)
System.Net Information: 0 : [1024] Associating SmtpClient#64923656 with SmtpTransport#44624228
System.Net Verbose: 0 : [1024] Exiting SmtpClient::.ctor()  -> SmtpClient#64923656
System.Net Information: 0 : [1024] Associating MailMessage#17654054 with Message#52727599
System.Net Verbose: 0 : [1024] SmtpClient#64923656::Send(MailMessage#17654054)
System.Net Information: 0 : [1024] SmtpClient#64923656::Send(DeliveryMethod=Network)
System.Net Information: 0 : [1024] Associating SmtpClient#64923656 with MailMessage#17654054
System.Net Information: 0 : [1024] Associating SmtpTransport#44624228 with SmtpConnection#14347911
System.Net Information: 0 : [1024] Associating SmtpConnection#14347911 with ServicePoint#51393439
System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Socket() 
System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Socket(InterNetworkV6#23)
System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#23264094::Socket() 
System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Connect(20:465#337754884)
System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Connect() 
System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Close()
System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Dispose()
System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#23264094::Close() 
System.Net Information: 0 : [1024] Associating SmtpConnection#14347911 with SmtpPooledStream#14303791
System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Receive()
System.Net.Sockets Verbose: 0 : [2404] Socket#26756241::Dispose()
System.Net.Sockets Error: 0 : [1024] Exception in the Socket#26756241::Receive - A blocking operation was interrupted by a call to WSACancelBlockingCall
System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Receive()   -> 0#0
System.Net Error: 0 : [1024] Exception in the SmtpClient#64923656::Send - Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall.
System.Net Error: 0 : [1024]    at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.DelegatedStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.BufferedReadStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Mail.SmtpReplyReaderFactory.ReadLines(SmtpReplyReader caller, Boolean oneLine)
   at System.Net.Mail.SmtpReplyReaderFactory.ReadLine(SmtpReplyReader caller)
   at System.Net.Mail.SmtpConnection.GetConnection(String Host, Int32 port)
   at System.Net.Mail.SmtpTransport.GetConnection(String Host, Int32 port)
   at System.Net.Mail.SmtpClient.GetConnection()
   at System.Net.Mail.SmtpClient.Send(MailMessage message)
System.Net Verbose: 0 : [1024] Exiting SmtpClient#64923656::Send() 
System.Net Information: 0 : [1024] Associating MailMessage#49584532 with Message#19699911

Ich googelte herum und fand heraus, dass System.Net.Mail Verbindungen an Port 587 unterstützt (Standardport für explizites SSL, das unverschlüsselt gestartet wird, dann eine STARTDLS ausgibt und dann zu einer verschlüsselten Verbindung wechselt: RFC 2228), jedoch kein implizites SSL (gesamte Verbindung) ist in eine SSL-Schicht gewickelt) ...

33
Idriss

Beispiel für das Senden von E-Mails über GMail, das ebenfalls SSL/465 verwendet. Eine kleinere Änderung des Codes sollte funktionieren!

using System.Web.Mail;
using System;
public class MailSender
{
    public static bool SendEmail(
        string pGmailEmail, 
        string pGmailPassword, 
        string pTo, 
        string pSubject,
        string pBody, 
        System.Web.Mail.MailFormat pFormat,
        string pAttachmentPath)
    {
    try
    {
        System.Web.Mail.MailMessage myMail = new System.Web.Mail.MailMessage();
        myMail.Fields.Add
            ("http://schemas.Microsoft.com/cdo/configuration/smtpserver",
                          "smtp.gmail.com");
        myMail.Fields.Add
            ("http://schemas.Microsoft.com/cdo/configuration/smtpserverport",
                          "465");
        myMail.Fields.Add
            ("http://schemas.Microsoft.com/cdo/configuration/sendusing",
                          "2");
        //sendusing: cdoSendUsingPort, value 2, for sending the message using 
        //the network.

        //smtpauthenticate: Specifies the mechanism used when authenticating 
        //to an SMTP 
        //service over the network. Possible values are:
        //- cdoAnonymous, value 0. Do not authenticate.
        //- cdoBasic, value 1. Use basic clear-text authentication. 
        //When using this option you have to provide the user name and password 
        //through the sendusername and sendpassword fields.
        //- cdoNTLM, value 2. The current process security context is used to 
        // authenticate with the service.
        myMail.Fields.Add
        ("http://schemas.Microsoft.com/cdo/configuration/smtpauthenticate","1");
        //Use 0 for anonymous
        myMail.Fields.Add
        ("http://schemas.Microsoft.com/cdo/configuration/sendusername",
            pGmailEmail);
        myMail.Fields.Add
        ("http://schemas.Microsoft.com/cdo/configuration/sendpassword",
             pGmailPassword);
        myMail.Fields.Add
        ("http://schemas.Microsoft.com/cdo/configuration/smtpusessl",
             "true");
        myMail.From = pGmailEmail;
        myMail.To = pTo;
        myMail.Subject = pSubject;
        myMail.BodyFormat = pFormat;
        myMail.Body = pBody;
        if (pAttachmentPath.Trim() != "")
        {
            MailAttachment MyAttachment = 
                    new MailAttachment(pAttachmentPath);
            myMail.Attachments.Add(MyAttachment);
            myMail.Priority = System.Web.Mail.MailPriority.High;
        }

        System.Web.Mail.SmtpMail.SmtpServer = "smtp.gmail.com:465";
        System.Web.Mail.SmtpMail.Send(myMail);
        return true;
    }
    catch (Exception ex)
    {
        throw;
    }
}
}
32
Andrew Siemer

Ich bin zu spät zu dieser Party, aber ich werde meine Annäherung für alle Passanten anbieten, die an einer Alternative interessiert sein könnten.

Wie in früheren Antworten angemerkt, ist der System.Net.MailSmtpClient Klasse unterstützt nicht Implizites SSL . Es unterstützt Explizites SSL , für das eine unsichere Verbindung zum SMTP-Server über Port 25 erforderlich ist, um die Transport Level Security (TLS) auszuhandeln. Ich habe mit dieser Subtilität über meine Probleme gebloggt hier .

Kurz gesagt, für SMTP über Implict SSL Port 465 muss TLS ausgehandelt werden , bevor eine Verbindung zum SMTP-Server hergestellt wird . Anstatt eine .Net SMTPS-Implementierung zu schreiben, habe ich mich an ein Hilfsprogramm mit dem Namen Stunnel gewandt. Es ist ein kleiner Dienst, mit dem Sie den Datenverkehr auf einem lokalen Port über SSL auf einen Remote-Port umleiten können.

HAFTUNGSAUSSCHLUSS: Stunnel verwendet Teile der OpenSSL-Bibliothek, für die kürzlich in allen wichtigen technischen Nachrichtenmedien ein hochkarätiger Exploit veröffentlicht wurde. Ich glaube, die neueste Version verwendet das gepatchte OpenSSL, aber bitte auf eigenes Risiko.

Sobald das Dienstprogramm installiert ist, wird ein kleiner Zusatz zur Konfigurationsdatei hinzugefügt:

; Example SSL client mode services
[my-smtps]
client = yes
accept = 127.0.0.1:465
connect = mymailserver.com:465

... weist den Stunnel-Dienst an, lokale Anforderungen an Port 465 an meinen Mail-Server an Port 465 umzuleiten. Dies geschieht über TLS, das den SMTP-Server am anderen Ende zufriedenstellt.

Mit diesem Dienstprogramm wird der folgende Code erfolgreich über Port 465 übertragen:

using System;
using System.Net;
using System.Net.Mail;

namespace RSS.SmtpTest
{
    class Program
    {
        static void Main( string[] args )
        {
            try {
                using( SmtpClient smtpClient = new SmtpClient( "localhost", 465 ) ) { // <-- note the use of localhost
                    NetworkCredential creds = new NetworkCredential( "username", "password" );
                    smtpClient.Credentials = creds;
                    MailMessage msg = new MailMessage( "[email protected]", "[email protected]", "Test", "This is a test" );
                    smtpClient.Send( msg );
                }
            }
            catch( Exception ex ) {
                Console.WriteLine( ex.Message );
            }
        }
    }
}

Der Vorteil hierbei ist, dass Sie Implict SSL und Port 465 als Sicherheitsprotokoll verwenden können, während Sie weiterhin die im Framework integrierten Send Mail-Methoden verwenden. Der Nachteil ist, dass die Verwendung eines Drittanbieter-Dienstes erforderlich ist, der für nichts anderes als diese spezielle Funktion nützlich sein kann.

13
Bob Mc

Es funktioniert mit System.Web.Mail (das als obsolet markiert ist):

private const string SMTP_SERVER        = "http://schemas.Microsoft.com/cdo/configuration/smtpserver";
private const string SMTP_SERVER_PORT   = "http://schemas.Microsoft.com/cdo/configuration/smtpserverport";
private const string SEND_USING         = "http://schemas.Microsoft.com/cdo/configuration/sendusing";
private const string SMTP_USE_SSL       = "http://schemas.Microsoft.com/cdo/configuration/smtpusessl";
private const string SMTP_AUTHENTICATE  = "http://schemas.Microsoft.com/cdo/configuration/smtpauthenticate";
private const string SEND_USERNAME      = "http://schemas.Microsoft.com/cdo/configuration/sendusername";
private const string SEND_PASSWORD      = "http://schemas.Microsoft.com/cdo/configuration/sendpassword";

System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage();

mail.Fields[SMTP_SERVER] = "tempurl.org";
mail.Fields[SMTP_SERVER_PORT] = 465;
mail.Fields[SEND_USING] = 2;
mail.Fields[SMTP_USE_SSL] = true;
mail.Fields[SMTP_AUTHENTICATE] = 1;
mail.Fields[SEND_USERNAME] = "username";
mail.Fields[SEND_PASSWORD] = "password";

System.Web.Mail.SmtpMail.Send(mail);

Wie beurteilen Sie die Verwendung von veralteten Namespaces?

10
Idriss

Versuchen Sie, diese kostenlose Open-Source-Alternative zu überprüfen https://www.nuget.org/packages/AIM .__ Es ist kostenlos und Open Source und verwendet dieselbe Weise wie System.Net .Mail verwendetUm E-Mails an implizite SSL-Ports zu senden, können Sie folgenden Code verwenden 

public static void SendMail()
{    
    var mailMessage = new MimeMailMessage();
    mailMessage.Subject = "test mail";
    mailMessage.Body = "hi dude!";
    mailMessage.Sender = new MimeMailAddress("[email protected]", "your name");
    mailMessage.To.Add(new MimeMailAddress("[email protected]", "your friendd's name")); 
// You can add CC and BCC list using the same way
    mailMessage.Attachments.Add(new MimeAttachment("your file address"));

//Mail Sender (Smtp Client)

    var emailer = new SmtpSocketClient();
    emailer.Host = "your mail server address";
    emailer.Port = 465;
    emailer.SslType = SslMode.Ssl;
    emailer.User = "mail sever user name";
    emailer.Password = "mail sever password" ;
    emailer.AuthenticationMode = AuthenticationType.Base64;
    // The authentication types depends on your server, it can be plain, base 64 or none. 
//if you do not need user name and password means you are using default credentials 
// In this case, your authentication type is none            
    emailer.MailMessage = mailMessage;
    emailer.OnMailSent += new SendCompletedEventHandler(OnMailSent);
    emailer.SendMessageAsync();
}

// A simple call back function:
private void OnMailSent(object sender, AsyncCompletedEventArgs asynccompletedeventargs)
{
if (e.UserState!=null)
    Console.Out.WriteLine(e.UserState.ToString());
if (e.Error != null)
{
    MessageBox.Show(e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else if (!e.Cancelled)
{
    MessageBox.Show("Send successfull!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
} 
8
Nil Null

Beim Versuch, eine Verbindung zum Rackspace-SSL-Port am 465 herzustellen, bin ich in VB.NET auf das gleiche Problem gestoßen (impliziert SSL). Ich habe https://www.nuget.org/packages/MailKit/ verwendet, um eine erfolgreiche Verbindung herzustellen. 

Das folgende Beispiel zeigt eine HTML-E-Mail-Nachricht.

Imports MailKit.Net.Smtp
Imports MailKit
Imports MimeKit

Sub somesub()
    Dim builder As New BodyBuilder()
    Dim mail As MimeMessage
    mail = New MimeMessage()
    mail.From.Add(New MailboxAddress("", c_MailUser))
    mail.To.Add(New MailboxAddress("", c_ToUser))
    mail.Subject = "Mail Subject"
    builder.HtmlBody = "<html><body>Body Text"
    builder.HtmlBody += "</body></html>"
      mail.Body = builder.ToMessageBody()

      Using client As New SmtpClient
        client.Connect(c_MailServer, 465, True)
        client.AuthenticationMechanisms.Remove("XOAUTH2") ' Do not use OAUTH2
        client.Authenticate(c_MailUser, c_MailPassword) ' Use a username / password to authenticate.
        client.Send(mail)
        client.Disconnect(True)
    End Using 

End Sub
5
Cody G.

Sie können auch über Port 465 eine Verbindung herstellen, aber aufgrund einiger Einschränkungen des System.Net.Mail-Namespaces müssen Sie möglicherweise Ihren Code ändern. Dies liegt daran, dass der Namespace nicht die Möglichkeit bietet, implizite SSL-Verbindungen herzustellen. Dies wird diskutiert unter http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx .

Es ist möglich, implizite Verbindungen herzustellen, ohne den jetzt veralteten Namespace System.Web.Mail verwenden zu müssen. Sie müssen jedoch auf das Microsoft CDO (Collaborative Data Object) zugreifen. Ich habe ein Beispiel für die Verwendung des CDOs in einer anderen Diskussion bereitgestellt ( GMail SMTP über C # .Net-Fehler an allen Ports ).

Hoffe das hilft!

4
Bryan Allred

Wenn es sich um implizites SSL handelt, scheint dies mit System.Net.Mail nicht möglich zu sein und wird bis jetzt nicht unterstützt.

http://blogs.msdn.com/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx

Um zu prüfen, ob es sich um implizites SSL handelt, versuchen Sie this.

4
Kinze

Ich weiß, dass ich zu spät zur Diskussion komme, aber ich denke, das kann für andere nützlich sein.

Ich wollte veraltetes Zeug vermeiden und nach vielem Fummeln habe ich einen einfachen Weg gefunden, an Server zu senden, die implizites SSL erfordern: Verwenden Sie NuGet und fügen Sie das MailKit-Paket zum Projekt hinzu. (Ich habe VS2017 zum Targeting von .NET 4.6.2 verwendet, aber es sollte mit niedrigeren .NET-Versionen funktionieren ...)

Dann musst du nur noch so etwas tun:

using MailKit.Net.Smtp;
using MimeKit;

var client = new SmtpClient();
client.Connect("server.name", 465, true);

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

if (needsUserAndPwd)
{
    // Note: only needed if the SMTP server requires authentication
    client.Authenticate (user, pwd);
}

var msg = new MimeMessage();
msg.From.Add(new MailboxAddress("[email protected]"));
msg.To  .Add(new MailboxAddress("[email protected]"));
msg.Subject = "This is a test subject";

msg.Body = new TextPart("plain") {
    Text = "This is a sample message body"
};

client.Send(msg);
client.Disconnect(true);

Natürlich können Sie es auch anpassen, um explizite SSL oder gar keine Transportsicherheit zu verwenden.

1
Luke

Wie in einem Kommentar bei 

http://blogs.msdn.com/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx

verwenden Sie mit System.Net.Mail Port 25 statt 465:

Sie müssen SSL = true und Port = 25 einstellen. Der Server antwortet auf Ihre Anfrage von ungeschützt 25 und stellt dann die Verbindung zu geschützt 465 her.

1
net_prog

Wenn Sie Zweifel an diesem Code haben, stellen Sie bitte Ihre Fragen. (Hier für Google Mail lautet die Portnummer 587.)

// code to Send Mail 
// Add following Lines in your web.config file 
//               <system.net>
//                  <mailSettings>
//                    <smtp>
//                        <network Host="smtp.gmail.com" port="587" userName="[email protected]" password="yyy"   defaultCredentials="false"/>
//                    </smtp>
//               </mailSettings>
//               </system.net>
// Add below lines in your config file inside appsetting tag <appsetting></appsetting>
//          <add key="emailFromAddress" value="[email protected]"/>
//       <add key="emailToAddress" value="[email protected]"/>
//        <add key="EmailSsl" value="true"/>

// Namespace Used

using System.Net.Mail;
     public static bool SendingMail(string subject, string content)
    {
       // getting the values from config file through c#
        string fromEmail = ConfigurationSettings.AppSettings["emailFromAddress"];
        string mailid = ConfigurationSettings.AppSettings["emailToAddress"];
        bool useSSL;
        if (ConfigurationSettings.AppSettings["EmailSsl"] == "true")
        {
            useSSL = true;
        }
        else
        {
            useSSL = false;
        }



        SmtpClient emailClient;
        MailMessage message;
        message = new MailMessage();
        message.From = new MailAddress(fromEmail);
        message.ReplyTo = new MailAddress(fromEmail);
        if (SetMailAddressCollection(message.To, mailid))
        {
            message.Subject = subject;
            message.Body = content;
            message.IsBodyHtml = true;
            emailClient = new SmtpClient();
            emailClient.EnableSsl = useSSL;
            emailClient.Send(message);
        }
        return true;
    }
    // if you are sending mail in group

    private static bool SetMailAddressCollection(MailAddressCollection toAddresses, string    mailId)
    {
        bool successfulAddressCreation = true;
        toAddresses.Add(new MailAddress(mailId));
        return successfulAddressCreation;
    }
0
RekhaShanmugam

Für Google Mail haben diese Einstellungen für mich funktioniert, die Linie ServicePointManager.SecurityProtocol war erforderlich. Da ich die Bestätigung in zwei Schritten eingerichtet habe, musste ich ein App-Passwort vom google App Password Generator . SmtpClient mailer = new SmtpClient(); mailer.Host = "smtp.gmail.com"; mailer.Port = 587; mailer.EnableSsl = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

0
user2584621