2009-06-18 61 views
32

Có cách nào với .NET Framework để gửi email thông qua máy chủ SSL SMTP trên cổng 465 không?Làm cách nào để gửi email qua SSL SMTP với .NET Framework?

Cách thông thường:

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

lần ra:

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 

Tôi googled xung quanh và thấy rằng System.Net.Mail hỗ trợ kết nối trên cổng 587 (cổng mặc định cho SSL Explicit bắt đầu không được mã hóa sau đó phát hành STARTDLS rồi chuyển sang kết nối được mã hóa: RFC 2228), nhưng không hỗ trợ SSL ngầm (toàn bộ kết nối được gói trong lớp SSL) ...

+1

[SmtpClient.EnableSsl Property] (http://msdn.microsoft.com/en-us/library/system.net.mail. smtpclient.enablessl.aspx) "Một phương thức kết nối thay thế là một phiên SSL được thiết lập trước khi bất kỳ lệnh giao thức nào được gửi đi. Phương thức kết nối này đôi khi được gọi là SMTP/SSL, SMTP qua SSL hoặc SMTPS và theo mặc định sử dụng cổng 465. Phương thức kết nối thay thế này bằng SSL hiện không được hỗ trợ. " FWIW – gerryLowry

Trả lời

32

Dưới đây là ví dụ về cách gửi email thông qua Gmail cũng sử dụng SSL/465. Việc chỉnh sửa mã nhỏ dưới đây sẽ hoạt động!

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; 
    } 
} 
} 
+17

System.Web.Mail không còn được dùng nữa. – David

+1

Mã cũ từ thư viện của tôi! Do đó, câu lệnh "Chỉnh sửa nhỏ mã bên dưới sẽ hoạt động!" –

+0

Đây có phải là phiên bản dành cho phiên bản .Net trước 4.0 không? –

9

Nó hoạt động ith System.Web.Mail (được đánh dấu là lỗi thời):

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

Quan điểm của bạn về việc sử dụng không gian tên cũ là gì?

+0

câu trả lời này có thể được cải thiện. Không có, từ, chủ đề, hoặc cơ thể ở đây. Đó là, bạn thiếu toàn bộ phần email. Chắc chắn, không khó, nhưng tại sao không chỉ đặt tất cả vào một chỗ? – Matthew

4

Bạn cũng có thể kết nối thông qua cổng 465, nhưng do một số hạn chế của không gian tên System.Net.Mail bạn có thể phải thay đổi mã của bạn. Điều này là do không gian tên không cung cấp khả năng tạo các kết nối SSL ngầm định. Điều này được thảo luận tại http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx.

Có thể tạo các kết nối ngầm mà không phải sử dụng không gian tên System.Web.Mail đã lỗi thời, nhưng bạn phải truy cập Microsoft CDO (Đối tượng dữ liệu cộng tác). Tôi đã cung cấp một ví dụ về cách sử dụng CDO trong một cuộc thảo luận khác (GMail SMTP via C# .Net errors on all ports).

Hy vọng điều này sẽ hữu ích!

-1

Nếu bất kỳ nghi ngờ trong mã này, xin vui lòng đặt câu hỏi của bạn (đây cho Số cổng gmail là 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

Câu hỏi đặt ra là sử dụng cổng 465, nhưng ví dụ của bạn là cho cổng 587. Có sự khác biệt đáng kể. – RobSiklos

5

Hãy thử để kiểm tra miễn phí này một mã nguồn mở thay thế https://www.nuget.org/packages/AIM Nó là miễn phí để sử dụng và mở nguồn và sử dụng một cách chính xác tương tự mà System.Net.Mail đang sử dụng để gửi email đến các cảng ssl ngầm bạn có thể sử dụng đoạn mã sau

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

bạn có thể cung cấp tài liệu về AIM này không? ? ? không tìm thấy tài liệu hoặc trang web nào trên sourceforge ??? –

10

tôi muộn để bên này nhưng tôi sẽ tắt er cách tiếp cận của tôi cho bất kỳ người qua đường nào có thể quan tâm đến giải pháp thay thế.

Như đã lưu ý trong các câu trả lời trước, lớp System.Net.MailSmtpClient không hỗ trợ SSL ngầm định.Nó hỗ trợ SSL rõ ràng, yêu cầu kết nối không an toàn với máy chủ SMTP qua cổng 25 để thương lượng bảo mật mức truyền tải (TLS). Tôi viết blog về những chuyến đi của tôi với sự tinh tế này here.

Tóm lại, SMTP qua cổng SSL Implict 465 yêu cầu TLS được thương lượng trước khi kết nối với máy chủ SMTP. Thay vì viết một triển khai Net SMT. Tôi đã chuyển sang một tiện ích có tên là Stunnel. Đó là một dịch vụ nhỏ cho phép bạn chuyển hướng lưu lượng truy cập trên một cổng cục bộ đến một cổng từ xa thông qua SSL.

TỪ BỎ ĐỐI TÁC: Stunnel sử dụng các phần của thư viện OpenSSL, gần đây có khai thác cao cấp được xuất bản trong tất cả các phương tiện truyền thông công nghệ lớn. Tôi tin rằng phiên bản mới nhất sử dụng OpenSSL được vá nhưng hãy tự chịu rủi ro.

Khi tiện ích được cài đặt một bổ sung nhỏ đến tập tin cấu hình:

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

... chỉ thị các dịch vụ Stunnel để định tuyến lại yêu cầu địa phương để cổng 465 đến máy chủ mail của tôi trên cổng 465. Điều này xảy ra trên TLS, đáp ứng máy chủ SMTP ở đầu bên kia.

Sử dụng tiện ích này, các mã sau đây sẽ truyền thành công qua cổng 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); 
      } 
     } 
    } 
} 

Vì vậy, lợi thế ở đây là bạn có thể sử dụng Implict SSL và cổng 465 là giao thức bảo mật trong khi vẫn sử dụng phương pháp email gửi được xây dựng trong khuôn khổ. Điểm bất lợi là nó đòi hỏi việc sử dụng một dịch vụ của bên thứ ba có thể không hữu ích cho bất cứ điều gì ngoài chức năng cụ thể này.

0

Để gmail các cài đặt này hoạt động đối với tôi, dòng ServicePointManager.SecurityProtocol là cần thiết. Vì tôi đã thiết lập xác minh 2 bước, tôi cần có Mật khẩu ứng dụng từ google app password generator. SmtpClient mailer = new SmtpClient(); mailer.Host = "smtp.gmail.com"; mailer.Port = 587; mailer.EnableSsl = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

4

Trong VB.NET trong khi cố gắng kết nối với cổng SSL của Rackspace trên 465 tôi gặp phải vấn đề tương tự (yêu cầu SSL ngầm). Tôi đã sử dụng https://www.nuget.org/packages/MailKit/ để kết nối thành công.

Sau đây là ví dụ về thông báo email 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 
+0

Điều này thực sự đã giúp tôi. Nó là một lựa chọn rất tốt để 'SmtpClient' mà không thể xử lý SSL ngầm. Ngoài ra, nó còn trưởng thành hơn nhiều so với AIM (được đề xuất trong một câu trả lời khác) và hoạt động tốt với UTF-8 (và các mã hóa khác). – Alexei

0

Tôi biết mình đang tham gia thảo luận, nhưng tôi nghĩ điều này có thể hữu ích cho người khác.

Tôi muốn tránh các nội dung không được dùng nữa và sau rất nhiều khó khăn, tôi tìm thấy một cách đơn giản để gửi tới máy chủ yêu cầu SSL ngầm: sử dụng NuGet và thêm MailKit package vào dự án. (Tôi đã sử dụng VS2017 nhắm mục tiêu NET 4.6.2 nhưng nó phải làm việc trên các phiên bản .NET thấp ...)

Sau đó, bạn sẽ chỉ cần làm một cái gì đó như thế này:

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

Tất nhiên bạn có thể cũng tinh chỉnh nó để sử dụng SSL rõ ràng hoặc không có bảo mật giao thông nào cả.

+0

Tôi đang sử dụng một mã dựa trên mã trên của bạn để gửi email qua mailkit, nhưng tôi quên lỗi, bạn có thể thấy ở đây, tôi sẽ rất vui vì bạn. https://stackoverflow.com/questions/46421323/sending-email-via-c-sharp-mailkit-mimekit-but-server-certificate-error-comes-i –

Các vấn đề liên quan