Вопрос по c#, .net, email, smtp – Как я могу отправлять электронные письма через SSL SMTP с помощью .NET Framework?

33

Есть ли способ .NET Framework для отправки электронной почты через SMTP-сервер SSL через порт 465?

Обычный способ:

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

время вышло:

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

Я погуглил и обнаружил, что System.Net.Mail поддерживает соединения через порт 587 (порт по умолчанию для явного SSL, который запускается незашифрованным, затем выдает STARTDLS, затем переключается на зашифрованное соединение: RFC 2228), но не поддерживает неявный SSL (полное соединение завернут в слой SSL) ...

SmtpClient.EnableSsl Property & quot; Альтернативный метод соединения - это когда сеанс SSL устанавливается перед отправкой любых протокольных команд. Этот метод подключения иногда называется SMTP / SSL, SMTP через SSL или SMTPS и по умолчанию использует порт 465. Этот альтернативный метод подключения с использованием SSL в настоящее время не поддерживается. & Quot; FWIW gerryLowry

Ваш Ответ

11   ответов
8

одом https://www.nuget.org/packages/AIM Он бесплатен для использования и с открытым исходным кодом и использует точно так же, как System.Net.Mail Для отправки электронной почты на неявные порты ssl вы можете использовать следующий код

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);
}
} 
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
32

как отправлять электронную почту через GMail, который также использует SSL / 465. Незначительная настройка кода ниже должна работать!

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;
    }
}
}
System.Web.Mail устарела.
Это предназначено для версий .Net до 4.0?
основанный наlink Вы правы, это не считается ошибкой, это по замыслу. Существует два типа аутентификации SSL для SMTP, и мы поддерживаем только один с System.Net.Mail (по замыслу) & # x2013; Явный SSL. И только Web.Mail может отправлять ssl письма
Похоже, это требование сейчас с Gmail? Это решение исправило мою проблему в 2017 году!
Старый код из моей библиотеки! Следовательно, утверждение «Незначительные изменения приведенного ниже кода должны работать!»
-1

пожалуйста, задавайте свои вопросы (здесь для gmail номер порта 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;
    }
Error: User Rate Limit Exceeded
1

что поздно присоединяюсь к обсуждению, но думаю, что это может быть полезно для других.

Я хотел избежать устаревших вещей, и после долгих хлопот я нашел простой способ отправки на серверы, требующие неявного SSL: используйте NuGet и добавьтеПакет MailKit к проекту. (Я использовал VS2017 для .NET 4.6.2, но он должен работать на более низких версиях .NET ...)

Тогда вам нужно всего лишь сделать что-то вроде этого:

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

Конечно, вы также можете настроить его на использование явного SSL или вообще без защиты транспорта.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededstackoverflow.com/questions/46421323/…
0

нужна была строка ServicePointManager.SecurityProtocol. Поскольку у меня есть двухэтапная проверка, мне нужно было получить пароль от приложениягенератор паролей приложения Google. SmtpClient mailer = new SmtpClient(); mailer.Host = "smtp.gmail.com"; mailer.Port = 587; mailer.EnableSsl = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

4

похоже, что он не может быть выполнен с System.Net.Mail и пока не поддерживается.

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

Чтобы проверить, является ли это неявным SSL, попробуйтеэтот.

5

нулся с той же проблемой (требуется неявный SSL). Я использовалhttps://www.nuget.org/packages/MailKit/ для того, чтобы успешно подключиться.

Ниже приведен пример сообщения электронной почты в формате HTML.

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
Error: User Rate Limit ExceededSmtpClientError: User Rate Limit Exceeded
10

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

Какова ваша точка зрения относительно устаревшего использования пространства имен?

Error: User Rate Limit Exceeded
4

но из-за некоторых ограничений пространства имен System.Net.Mail вам, возможно, придется изменить свой код. Это связано с тем, что пространство имен не позволяет создавать неявные SSL-соединения. Это обсуждается наhttp://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx.

Можно создавать неявные соединения без необходимости использования устаревшего пространства имен System.Web.Mail, но вам нужно получить доступ к Microsoft CDO (объект данных для совместной работы). Я привел пример использования CDO в другом обсуждении (GMail SMTP через C #. Net ошибки на всех портах).

Надеюсь это поможет!

1

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

с System.Net.Mail используйте порт 25 вместо 465:

You must set SSL=true and Port=25. Server responds to your request from unprotected 25 and then throws connection to protected 465.

Error: User Rate Limit Exceededsupport.microsoft.com/en-us/help/950260/… I verifiedError: User Rate Limit ExceededdoesError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
13

но я предложу свой подход для всех прохожих, которые могут быть заинтересованы в альтернативе.

Как отмечалось в предыдущих ответах,System.Net.Mail SmtpClient класс не поддерживаетImplicit SSL, Это поддерживаетExplicit SSL, что требует небезопасного соединения с SMTP-сервером через порт 25 для согласования безопасности транспортного уровня (TLS). Я написал о моих страданиях с этой тонкостьюВот.

Короче говоря, для SMTP через порт Implict SSL 465 требуется согласование TLSbefore подключение к SMTP-серверу. Вместо того, чтобы писать .Net SMTPS, я обратился к утилите с именемStunnel, Это небольшая служба, которая позволяет перенаправлять трафик с локального порта на удаленный порт по протоколу SSL.

DISCLAIMER: Stunnel uses portions of the OpenSSL library, which recently had a high-profile exploit published in all major tech news media. I believe the latest version uses the patched OpenSSL but please use at your own risk.

После того, как утилита установлена, небольшое дополнение к файлу конфигурации:

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

... инструктирует службу Stunnel перенаправлять локальные запросы на порт 465 на мой почтовый сервер через порт 465. Это происходит по протоколу TLS, который удовлетворяет SMTP-серверу на другом конце.

Используя эту утилиту, следующий код будет успешно передавать через порт 465:

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

Таким образом, преимущество в том, что вы можете использовать Implict SSL и порт 465 в качестве протокола безопасности, в то же время используя методы отправки почты, встроенные в платформу. Недостатком является то, что для этого требуется использование стороннего сервиса, который может быть бесполезен ни для чего, кроме этой конкретной функции.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы