c# - form - ¿Cómo puedo enviar correos electrónicos a través de SMTP SSL con.NET Framework?
enviar correo c# sin credenciales (11)
Aquí hay un ejemplo de cómo enviar correos electrónicos a través de GMail que también usa SSL / 465. ¡Un pequeño ajuste del código a continuación debería funcionar!
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;
}
}
}
¿Hay alguna manera con .NET Framework de enviar correos electrónicos a través de un servidor SSL SMTP en el puerto 465?
La forma habitual:
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);
se acabó el tiempo:
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
Busqué en Google y descubrí que System.Net.Mail admite conexiones en el puerto 587 (puerto predeterminado para SSL explícito que comienza sin encriptar y luego emite un STARTDLS luego cambia a una conexión encriptada: RFC 2228), pero no admite SSL implícito (conexión completa está envuelto en una capa SSL) ...
Como se indica en un comentario en
con System.Net.Mail, use el puerto 25 en lugar de 465:
Debe establecer SSL = verdadero y Puerto = 25. El servidor responde a su solicitud desde 25 sin protección y luego lanza la conexión al 465 protegido.
En VB.NET mientras trataba de conectarme al puerto SSL de Rackspace en 465, encontré el mismo problema (requiere SSL implícito). Hice uso de https://www.nuget.org/packages/MailKit/ para conectarme con éxito.
El siguiente es un ejemplo de un mensaje de correo electrónico 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
Funciona con System.Web.Mail (que está marcado como obsoleto):
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);
¿Cuál es su punto de vista con respecto al uso obsoleto del espacio de nombres?
Intente comprobar esta alternativa gratuita de código abierto https://www.nuget.org/packages/AIM Es de uso gratuito y de código abierto y utiliza exactamente de la misma manera que System.Net.Mail está utilizando Para enviar correo electrónico a ssl implícito puertos que puede usar el siguiente código
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);
}
}
Llego tarde a esta fiesta, pero ofreceré mi enfoque para cualquier transeúnte que pueda estar interesado en una alternativa.
Como se indicó en respuestas anteriores, la clase System.Net.Mail
SmtpClient
no es compatible con SSL implícito . Admite SSL explícito , que requiere una conexión insegura al servidor SMTP a través del puerto 25 para negociar la seguridad del nivel de transporte (TLS). Blogé sobre mis tribulaciones con esta sutileza here .
En resumen, SMTP sobre el puerto SSL Implicat 465 requiere que se negocie TLS antes de conectarse al servidor SMTP. En lugar de escribir una implementación .Net SMTPS, recurrí a una utilidad llamada Stunnel . Es un servicio pequeño que le permitirá redirigir el tráfico en un puerto local a un puerto remoto a través de SSL.
EXENCIÓN DE RESPONSABILIDAD: Stunnel utiliza porciones de la biblioteca OpenSSL, que recientemente tuvo un exploit de alto perfil publicado en todos los principales medios de noticias de tecnología. Creo que la última versión usa el parche OpenSSL, pero utilícelo bajo su propio riesgo.
Una vez que se instala la utilidad, una pequeña adición al archivo de configuración:
; Example SSL client mode services
[my-smtps]
client = yes
accept = 127.0.0.1:465
connect = mymailserver.com:465
... instruye al servicio Stunnel para redirigir las solicitudes locales al puerto 465 a mi servidor de correo en el puerto 465. Esto sucede a través de TLS, que satisface al servidor SMTP en el otro extremo.
Usando esta utilidad, el siguiente código transmitirá con éxito a través del puerto 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 );
}
}
}
}
Entonces, la ventaja aquí es que puede usar Implict SSL y el puerto 465 como protocolo de seguridad mientras sigue utilizando los métodos de envío de correo integrados en el marco. La desventaja es que requiere el uso de un servicio externo que puede no ser útil para nada más que esta función específica.
Para gmail estas configuraciones me funcionaron, la línea ServicePointManager.SecurityProtocol era necesaria. Como configuré la verificación en 2 pasos, necesitaba una contraseña de aplicación del generador de contraseñas de la aplicación google . SmtpClient mailer = new SmtpClient(); mailer.Host = "smtp.gmail.com"; mailer.Port = 587; mailer.EnableSsl = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
Sé que me uniré tarde a la discusión, pero creo que esto puede ser útil para otros.
Quería evitar las cosas obsoletas y después de mucho toquetear encontré una forma sencilla de enviar a servidores que requieren SSL implícito: use NuGet y agregue el paquete MailKit al proyecto. (Utilicé VS2017 apuntando a .NET 4.6.2 pero debería funcionar en versiones inferiores de .NET ...)
Entonces solo necesitarás hacer algo como esto:
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);
Por supuesto, también puede modificarlo para usar SSL explícito o sin seguridad de transporte.
Si se trata de SSL implícito, parece que no se puede hacer con System.Net.Mail y aún no es compatible.
Para comprobar si es SSL implícita, intente this.
Si tiene alguna duda en este código, haga sus preguntas (Aquí el número de puerto de Gmail es 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;
}
También puede conectarse a través del puerto 465, pero debido a algunas limitaciones del espacio de nombres System.Net.Mail, es posible que deba modificar su código. Esto se debe a que el espacio de nombres no ofrece la capacidad de realizar conexiones SSL implícitas. Esto se analiza en http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx .
Es posible realizar conexiones implícitas sin tener que utilizar el espacio de nombres System.Web.Mail ahora obsoleto, pero tiene que acceder al Microsoft CDO (Collaborative Data Object). He proporcionado un ejemplo de cómo usar el CDO en otra discusión ( GMail SMTP a través de errores C # .Net en todos los puertos ).
¡Espero que esto ayude!